ChatGPT解决这个技术问题 Extra ChatGPT

在 HTML/CSS 中将图像转换为灰度

有没有一种简单的方法可以仅使用 HTML/CSS 以灰度显示彩色位图?

它不需要与 IE 兼容(我想它不会)——如果它在 FF3 和/或 Sf3 中工作,那对我来说已经足够了。

我知道我可以同时使用 SVG 和 Canvas,但现在这似乎需要做很多工作。

有没有真正懒人的方法来做到这一点?

“它不需要与 IE 兼容(我想它不会)”?? IE 提供了一组 DX filters since 1997 (IE4),仅使用 CSS 和更多功能即可完成这项工作。现在他们有 dropped DX filters in IE10 并且严格遵循基于标准 SVG 的过滤器。您可能想看看 thisthis demo
@vulcanraven 这不是真正的“纯粹的 CSS”——如果你在 IE 中禁用活动脚本,过滤器就会停止工作。
@robertc,那是对的。相反,如果您在任何浏览器中禁用 javascript,包括 Stackoverflow 在内的几乎所有 RIA 都将停止工作(除非 Web 开发人员实现了仅 HTML 版本的回退)。
只需使用 CSS stackoverflow.com/questions/286275/gray-out-image-with-css/… 在这个问题中获得我的答案

2
23 revs, 8 users 80%

Support for CSS filters has landed in Webkit. 所以我们现在有了一个跨浏览器的解决方案。

img {过滤器:灰色; /* IE6-9 */ -webkit-filter: grayscale(1); /* Google Chrome, Safari 6+ & Opera 15+ */ filter: grayscale(1); /* Microsoft Edge 和 Firefox 35+ */ } /* 禁用悬停灰度 */ img:hover { -webkit-filter: grayscale(0);过滤器:无; }

Internet Explorer 10 怎么样?

您可以使用像 gray 这样的 polyfill。


@CamiloMartin CSS 过滤器仅受 Chrome 18+ 支持
更新:最新稳定版 Google Chrome (19) 现在支持 CSS 过滤器。耶! =)
Opera有什么解决方案吗?
那么,IE10的解决方案是什么?
后人:@TomAuger,此 Q&A 有针对 IE10 的具体说明。
s
smottt

brillout.com's answerRoman Nurik's answer 之后,稍微放宽“无 SVG”要求,您可以仅使用单个 SVG 文件和一些 CSS 在 Firefox 中对图像进行去饱和处理。

您的 SVG 文件将如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">
    <filter id="desaturate">
        <feColorMatrix type="matrix" values="0.3333 0.3333 0.3333 0 0
                                             0.3333 0.3333 0.3333 0 0
                                             0.3333 0.3333 0.3333 0 0
                                             0      0      0      1 0"/>
    </filter>
</svg>

将其另存为resources.svg,从现在开始可以将其重用于您想要更改为灰度的任何图像。

在您的 CSS 中,您使用 Firefox 特定的 filter 属性引用过滤器:

.target {
    filter: url(resources.svg#desaturate);
}

如果您愿意,也可以添加 MS 专有的,apply that class to any image you want to convert to greyscale (works in Firefox >3.5, IE8)

editHere's a nice blog post 描述了在 SalmanPK 的答案中使用新的 CSS3 filter 属性与此处描述的 SVG 方法相一致。使用这种方法,你最终会得到类似的东西:

img.desaturate{
    filter: gray; /* IE */
    -webkit-filter: grayscale(1); /* Old WebKit */
    -webkit-filter: grayscale(100%); /* New WebKit */
    filter: url(resources.svg#desaturate); /* older Firefox */
    filter: grayscale(100%); /* Current draft standard */
}

Further browser support info here


在 webkit 你这样做:-webkit-filter: grayscale(100%); 然后这个:-webkit-filter: grayscale(0); 删除它。
@SeanJA 感谢您的更新,WebKit 开始实现这些东西in December
我在我的 linux 笔记本电脑和我的 win7 机器上都在 chrome beta 中看到了它。它似乎在 linux 的 chrome stable 中不起作用(但话又说回来,linux 的版本可能落后于 windows)。
这种方法在 Chrome 中对我来说很好,但在 Safari 中无效。在 FF 中,它使我的图像在悬停之前不可见。
m
mquandalle

对于 Firefox,您不需要创建 filter.svg 文件,您可以使用 data URI scheme

占用第一个答案的css代码给出:

filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
filter: grayscale(100%); /* Current draft standard */
-webkit-filter: grayscale(100%); /* New WebKit */
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%); 
-o-filter: grayscale(100%);
filter: gray; /* IE6+ */

注意用您的文件编码替换“utf-8”字符串。

这种方法应该比另一种更快,因为浏览器不需要进行第二次 HTTP 请求。


只是为了避免头痛:YUI Compressor 去除数据 url 中的空格。因此,如果您想使用此解决方案,您可能会考虑使用另一个缩小器。
@Malte 或者也许只是用 "%20" 字符串替换空格?
@mquandalle 不幸的是 IE10 不支持 filter:gray blogs.msdn.com/b/ie/archive/2011/12/07/…
在 Firefox 上,我的灰色很浅。有什么办法可以增加对比度或稍微变暗?其他浏览器看起来很棒。
C
Community

更新:我把它做成了一个完整的 GitHub 存储库,包括 IE10 和 IE11 的 JavaScript polyfill:https://github.com/karlhorky/gray

我最初使用 SalmanPK's answer,但后来创建了以下变体以消除 SVG 文件所需的额外 HTTP 请求。内联 SVG 在 Firefox 10 及以上版本中工作,低于 10 的版本不再占全球浏览器市场的 1%。

从那以后,我一直在 this blog post 上更新解决方案,添加对淡出颜色的支持、对 SVG 的 IE 10/11 支持以及演示中的部分灰度。

img.grayscale {
  /* Firefox 10+, Firefox on Android */
  filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='grayscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0'/></filter></svg>#grayscale");

  /* IE 6-9 */
  filter: gray;

  /* Chrome 19+, Safari 6+, Safari 6+ iOS */
  -webkit-filter: grayscale(100%);
}

img.grayscale.disabled {
  filter: none;
  -webkit-filter: grayscale(0%);
}

A
AdamMcquiff

仅使用 CSS 实现灰度的最简单方法是通过 filter 属性。

img {
    -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
    filter: grayscale(100%);
}

该属性仍未得到完全支持,并且仍然需要 -webkit-filter 属性才能在所有浏览器中提供支持。


c
chrismacp

如果您能够使用 JavaScript,那么此脚本可能就是您正在寻找的。它可以跨浏览器工作,到目前为止对我来说工作正常。您不能将它与从不同域加载的图像一起使用。

http://james.padolsey.com/demos/grayscale/


链接已损坏,这就是为什么您应该始终复制链接的内容而不是仅仅引用它,我知道您的回答是 12 岁,我感谢您
C
Community

今天刚遇到同样的问题。我最初使用 SalmanPK solution,但发现 FF 和其他浏览器之间的效果不同。这是因为转换矩阵只对亮度起作用,而不像 Chrome/IE 中的过滤器那样对亮度起作用。令我惊讶的是,我发现 SVG 中的替代和更简单的解决方案也适用于 FF4+ 并产生更好的结果:

<svg xmlns="http://www.w3.org/2000/svg">
  <filter id="desaturate">
    <feColorMatrix type="saturate" values="0"/>
  </filter>
</svg>

使用CSS:

img {
    filter: url(filters.svg#desaturate); /* Firefox 3.5+ */
    filter: gray; /* IE6-9 */
    -webkit-filter: grayscale(1); /* Google Chrome & Safari 6+ */
}

还有一点需要注意的是,IE10 在标准兼容模式下不再支持“过滤器:灰色:”,因此需要在标头中切换兼容模式才能工作:

<meta http-equiv="X-UA-Compatible" content="IE=9" />

似乎是一个更好、更简单的解决方案——如果 SalmanPK 和 mquandalle 更新他们的解决方案会很好。显然他们使用的矩阵is broken <br><br>这是嵌入式数据版本:filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'saturate\' values=\'0\'/></filter></svg>#grayscale");
v
vals

一段时间以来,现代浏览器上已经有一种新的方法可以做到这一点。

background-blend-mode 可以让你得到一些有趣的效果,其中之一就是灰度转换

设置在白色背景上的值 luminosity 允许它。 (悬停以灰色查看)

.test { 宽度:300px;高度:200px;背景:url(“http://placekitten.com/1000/750”),白色;背景尺寸:封面; } .test:hover { 背景混合模式:亮度; }

亮度取自图像,颜色取自背景。因为它总是白色的,所以没有颜色。

但它允许更多。

您可以为效果设置 3 层设置动画。第一个是图像,第二个是黑白渐变。如果对此应用乘法混合模式,您将在白色部分获得与以前一样的白色结果,但在黑色部分上的原始图像(乘以白色得到白色,乘以黑色没有效果。)

在渐变的白色部分,你会得到和以前一样的效果。在渐变的黑色部分,您将图像与自身混合,结果是未修改的图像。

现在,所需要的只是移动渐变以获得动态效果:(悬停以查看颜色)

div { 宽度:600px;高度:400px; } .test { 背景: url("http://placekitten.com/1000/750"), 线性渐变(0deg, 白色 33%, 黑色 66%), url("http://placekitten.com/1000 /750");背景位置:0px 0px,0px 0%,0px 0px;背景尺寸:封面,100% 300%,封面;背景混合模式:亮度,乘法;过渡:全2; } .test:hover { 背景位置:0px 0px, 0px 66%, 0px 0px; }

reference

compatibility matrix


@Andy 我在现代浏览器中开始回答
如果图像使用 img 标记而不是 background: url(),您如何应用它?
@MohammadElbanna您需要使用混合混合模式而不是背景混合模式
R
Roman Nurik

即使使用 CSS3 或专有 -webkit--moz- CSS 属性,看起来也不可能(目前)。

但是,我确实发现 this post from last June 在 HTML 上使用了 SVG 过滤器。在任何当前浏览器中都不可用(演示暗示了自定义 WebKit 构建),但作为概念证明非常令人印象深刻。


J
Joran Den Houting

对于在其他答案中询问被忽略的 IE10+ 支持的人,请查看这段 CSS:

img.grayscale:hover {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale");
}

svg {
    background:url(http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s400/a2cf7051-5952-4b39-aca3-4481976cb242.jpg);
}

svg image:hover {
    opacity: 0;
}

应用于此标记:

<!DOCTYPE HTML>
<html>
<head>

    <title>Grayscaling in Internet Explorer 10+</title>

</head>
<body>

    <p>IE10 with inline SVG</p>
    <svg xmlns="http://www.w3.org/2000/svg" id="svgroot" viewBox="0 0 400 377" width="400" height="377">
      <defs>
         <filter id="filtersPicture">
           <feComposite result="inputTo_38" in="SourceGraphic" in2="SourceGraphic" operator="arithmetic" k1="0" k2="1" k3="0" k4="0" />
           <feColorMatrix id="filter_38" type="saturate" values="0" data-filterid="38" />
        </filter>
      </defs>
      <image filter="url(&quot;#filtersPicture&quot;)" x="0" y="0" width="400" height="377" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s1600/a2cf7051-5952-4b39-aca3-4481976cb242.jpg" />
    </svg>

</body>
</html>

如需更多演示,请查看 IE testdrive 的 CSS3 Graphics section 和这个旧的 IE 博客 http://blogs.msdn.com/b/ie/archive/2011/10/14/svg-filter-effects-in-ie10.aspx


b
brillout

在 Internet Explorer 中使用过滤器属性。

在 webkit 和 Firefox 中,目前无法仅使用 CSS 对图像进行去饱和处理。因此,您将需要使用画布或 SVG 作为客户端解决方案。

但我认为使用 SVG 更优雅。查看我的博文,了解适用于 Firefox 和 webkit 的 SVG 解决方案:http://webdev.brillout.com/2010/10/desaturate-image-without-javascript.html

严格来说,因为 SVG 是 HTML,所以解决方案是纯 html+css :-)


嗨 brillout。我注意到你的灰度实际上在 safari 中失败了。有后续吗?谢谢
SVG 不是 HTML。这是一个完全不同的规格。
@CamiloMartin Here is SVG in the HTML spec
@robertc 该链接是关于将 SVG 放入 HTML,但这里是 SVG spec,这里是 HTML spec。两者彼此相似(或与 XML 相似)这一事实并不意味着它们是同一件事......
但它链接到 reference 中的 SVG 规范...它没有定义 SVG,只是说浏览器应该解析它。在这方面它就像 Javascript 或 CSS。
Y
YuZA

也许这种方式可以帮助你

img {
    -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
    filter: grayscale(100%);
}

w3schools.org


C
Community

如果我记得正确使用专有的 CSS 属性,实际上使用 IE 更容易做到这一点。试试这个来自 http://www.ssi-developer.net/css/visual-filters.shtmlFILTER: Gray

Ax 的方法只是使图像透明并在其后有黑色背景。我敢肯定你会说这是灰度。

尽管您不想使用 Javascript,但我认为您必须使用它。您也可以使用服务器端语言来做到这一点。


我什至没有 Windows 盒子,所以谢谢,但这对我来说用处不大。
在这种情况下,您可以使用带有 IE 的虚拟机查看它,实现 ax 的方法或使用画布……请注意,使用画布对大图像进行灰度化可能会对 Javascript 引擎造成很大负担。
第 4 版 起,filter: gray 就出现在 Internet Explorer 中。他们为他们的产品做了很多废话——没错! - 但他们在这些东西上真的超前了
S
Shalom Craimer

如果您愿意使用 Javascript,那么您可以使用画布将图像转换为灰度。由于 Firefox 和 Safari 支持 <canvas>,它应该可以工作。

所以我用谷歌搜索了“canvas grayscale”,第一个结果是http://www.permadi.com/tutorial/jsCanvasGrayscale/index.html,它似乎有效。


h
hjindal

从当前版本 19.0.1084.46 添加了对 webkit 中原生 CSS 过滤器的支持

所以 -webkit-filter: grayscale(1) 会起作用,这比 webkit 的 SVG 方法更容易......


J
James van Dyke

这是 LESS 的 mixin,可让您选择任何不透明度。以不同的百分比为纯 CSS 自己填写变量。

这里的提示很巧妙,它对矩阵使用饱和类型,所以你不需要做任何花哨的事情来改变百分比。

.saturate(@value:0) {
    @percent: percentage(@value);

    filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='saturate'%20values='@value'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
    filter: grayscale(@percent); /* Current draft standard */
    -webkit-filter: grayscale(@percent); /* New WebKit */
    -moz-filter: grayscale(@percent);
    -ms-filter: grayscale(@percent);
    -o-filter: grayscale(@percent);
}

然后使用它:

img.desaturate {
    transition: all 0.2s linear;
    .saturate(0);
    &:hover {
        .saturate(1);
    }
}

m
maťo

你不需要使用这么多前缀来充分使用,因为如果你为旧的火狐选择前缀,你不需要为新的火狐使用前缀。

所以为了充分利用,足够使用这个代码:

img.grayscale {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale"); /* Firefox 10+, Firefox on Android */
    filter: gray; /* IE6-9 */
    -webkit-filter: grayscale(100%); /* Chrome 19+, Safari 6+, Safari 6+ iOS */
}

img.grayscale.disabled {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale");
    filter: none;
    -webkit-filter: grayscale(0%);
}

s
smottt

作为对其他答案的补充,可以在 FF 上对图像进行一半去饱和,而无需 SVG 矩阵的头痛:

<feColorMatrix type="saturate" values="$v" />

其中 $v01 之间。它相当于 filter:grayscale(50%);

现场示例:

.desaturate { filter: url("#desaturate"); -webkit-filter:灰度(50%); } figcaption{ 背景:rgba(55, 55, 136, 1);填充:4px 98px 0 18px;白颜色;显示:内联块;边框左上角半径:8px;边框右上角半径:100%;字体系列:“Helvetica”; }

原创
半灰

Reference on MDN


G
G-Cyrillus

是旧浏览器的另一种选择是使用由伪元素或内联标签产生的掩码。

通过 rgba() 或 translucide png 将绝对定位悬停在 img (或无需单击或选择的文本区域)可以密切模仿色标的效果。

它不会给出一个单一的色阶,但会使颜色超出范围。

通过伪元素用 10 种不同颜色的代码笔测试,最后是灰色。 http://codepen.io/gcyrillus/pen/nqpDd(重新加载以切换到另一张图片)


A
Andrew Morton

基于 robertc's answer

要从彩色图像正确转换为灰度图像,而不是像这样使用矩阵:

0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0      0      0      1 0

您应该像这样使用转换矩阵:

0.299 0.299 0.299 0
0.587 0.587 0.587 0
0.112 0.112 0.112 0
0     0     0     1

这应该适用于基于 RGBA(红绿蓝阿尔法)模型的所有类型的图像。

有关为什么您应该使用矩阵的更多信息,我更可能发布了 robertc 的一个检查以下链接:

亮度和色差信号

Margus 对问题的回答:“colorvalue 中的灰度值”@stackoverflow 部分:编辑 2:@Hans Passant

Charles A. Bouman - 普渡大学 - 模拟电视第 20 和 21 页

在这里你可以找到一些 C# 和 VB 代码


我同意 0.3333 是错误的; 0.2126 0.7152 0.0722 0 0 似乎等同于 <fecolormatrix type="saturate" values="0">
“亮度和色差信号”的链接也断开了。我找不到替代品。
r
richardtallent

一个糟糕但可行的解决方案:使用 Flash 对象渲染图像,然后为您提供 Flash 中所有可能的转换。

如果您的用户正在使用最先进的浏览器并且 Firefox 3.5 和 Safari 4 支持它(我不知道是否会这样做),您可以调整图像的 CSS 颜色配置文件属性,将其设置为灰度 ICC个人资料网址。但这是很多如果的!


D
Dany Maor

您可以使用 jFunc 的功能之一 - 使用功能“jFunc_CanvasFilterGrayscale”http://jfunc.com/jFunc-functions.aspx


N
Nicholas TJ

试试这个 jquery 插件。虽然,这不是一个纯粹的 HTML 和 CSS 解决方案,但它是实现你想要的一种懒惰的方式。您可以自定义灰度以最适合您的使用。使用它如下:

$("#myImageID").tancolor();

有一个交互式 demo。你可以玩弄它。

查看有关用法的文档,它非常简单。 docs


d
dval

对于 Firefox 中的灰度百分比,请改用 saturate filter:(搜索“饱和”)

filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='saturate'><feColorMatrix in='SourceGraphic' type='saturate' values='0.2' /></filter></svg>#saturate"

F
Frames Catherine White

如果您或将来面临类似问题的其他人对 PHP 持开放态度。 (我知道你说的是 HTML/CSS,但也许你已经在后端使用 PHP)这是一个 PHP 解决方案:

我从 PHP GD 库中得到它并添加了一些变量来自动化该过程......

<?php
$img = @imagecreatefromgif("php.gif");

if ($img) $img_height = imagesy($img);
if ($img) $img_width = imagesx($img);

// Create image instances
$dest = imagecreatefromgif('php.gif');
$src = imagecreatefromgif('php.gif');

// Copy and merge - Gray = 20%
imagecopymergegray($dest, $src, 0, 0, 0, 0, $img_width, $img_height, 20);

// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);

imagedestroy($dest);
imagedestroy($src);

?>

@Tom,根据对原始问题的投票和收藏,OP 并不是唯一一个想知道这是否可能的人。当然,这个答案可能会违反规则,但我认为否决一个可能对很多人有用的答案没有意义。
@Tom,我虽然可能不是对这个问题的准确回答,但它可能会派上用场,因为它实际上“解决”了灰度问题而没有 javascript 的“麻烦”,也许他甚至没有考虑或了解 PHP GD,无意伤害。 @mlms13 正是这一点,谢谢:)
那是我的错,关于其他用户可以从这篇文章中受益的“想法”从我的脑海中消失了。道歉@Trufa。
这确实帮助了我,在其他几个死胡同之后让我走上了正确的轨道。我发现使用“imagefilter($source, IMG_FILTER_GRAYSCALE);”虽然给出了更好的结果。 (仅限 PHP 5)
投了反对票,因为它几乎是题外话。在服务器端对图像进行灰度化与 CSS/HTML 完全不同。