648

有没有一种简单的方法来显示灰度颜色位图HTML/CSS

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

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

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

4

25 回答 25

771

对 CSS 过滤器的支持已经登陆 Webkit。 所以我们现在有了一个跨浏览器的解决方案。

img {
  filter: gray; /* IE6-9 */
  -webkit-filter: grayscale(1); /* Google Chrome, Safari 6+ & Opera 15+ */
  filter: grayscale(1); /* Microsoft Edge and Firefox 35+ */
}

/* Disable grayscale on hover */
img:hover {
  -webkit-filter: grayscale(0);
  filter: none;
}
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/04/Wikimedia_Canadian_Community_Logo.svg/240px-Wikimedia_Canadian_Community_Logo.svg.png">


Internet Explorer 10 怎么样?

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

于 2011-12-23T03:45:01.577 回答
130

Following on from brillout.com's answer, and also Roman Nurik's answer, and relaxing somewhat the the 'no SVG' requirement, you can desaturate images in Firefox using only a single SVG file and some CSS.

Your SVG file will look like this:

<?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>

Save that as resources.svg, it can be reused from now on for any image you want to change to greyscale.

In your CSS you reference the filter using the Firefox specific filter property:

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

Add the MS proprietary ones too if you feel like it, apply that class to any image you want to convert to greyscale (works in Firefox >3.5, IE8).

edit: Here's a nice blog post which describes using the new CSS3 filter property in SalmanPK's answer in concert with the SVG approach described here. Using that approach you'd end up with something like:

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.

于 2010-10-26T23:45:45.277 回答
85

对于 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 请求。

于 2012-11-30T06:57:02.373 回答
28

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

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

从那以后,我一直在此博客文章中更新解决方案,添加对退色的支持、对 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%);
}
于 2012-11-01T19:32:33.247 回答
14

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

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

于 2010-12-08T15:41:21.377 回答
14

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

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

该属性仍不完全受支持,并且仍需要该-webkit-filter属性以支持所有浏览器。

于 2016-11-04T09:34:07.973 回答
12

今天刚遇到同样的问题。我最初使用SalmanPK 解决方案,但发现 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" />
于 2012-03-05T16:04:24.243 回答
8

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

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

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

.test {
  width: 300px;
  height: 200px;
    background: url("http://placekitten.com/1000/750"), white; 
    background-size: cover;
}

.test:hover {
    background-blend-mode: luminosity;
}
<div class="test"></div>

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

但它允许更多。

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

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

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

div {
    width: 600px;
    height: 400px;
}

.test {
    background: url("http://placekitten.com/1000/750"), 
linear-gradient(0deg, white 33%, black 66%), url("http://placekitten.com/1000/750"); 
    background-position: 0px 0px, 0px 0%, 0px 0px;
    background-size: cover, 100% 300%, cover;
    background-blend-mode: luminosity, multiply;
    transition: all 2s;
}

.test:hover {
    background-position: 0px 0px, 0px 66%, 0px 0px;
}
<div class="test"></div>

参考

兼容性矩阵

于 2015-03-02T18:17:14.390 回答
7

对于在其他答案中询问被忽略的 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 图形部分和这个旧的 IE 博客http://blogs.msdn.com/b/ie/archive/2011/10/14/svg-filter-effects-in-ie10.aspx

于 2013-04-28T05:23:54.677 回答
7

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

但是,我确实发现了去年 6 月的这篇文章,它在 HTML 上使用了 SVG 过滤器。在任何当前浏览器中都不可用(演示暗示了自定义 WebKit 构建),但作为概念证明非常令人印象深刻。

于 2009-06-11T04:05:36.613 回答
7

在 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 :-)

于 2010-10-26T18:58:22.623 回答
4

Maybe this way help you

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

w3schools.org

于 2016-05-03T15:12:47.183 回答
3

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

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

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

于 2009-03-04T05:20:43.320 回答
2

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

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

$v之间在哪里。它相当于.01filter:grayscale(50%);

现场示例:

.desaturate {
    filter: url("#desaturate");
    -webkit-filter: grayscale(50%);
}
figcaption{
    background: rgba(55, 55, 136, 1);
    padding: 4px 98px 0 18px;
    color: white;
    display: inline-block;
    border-top-left-radius: 8px;
    border-top-right-radius: 100%;
    font-family: "Helvetica";
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  <filter id="desaturate">
  	<feColorMatrix type="saturate" values="0.4"/>
  </filter>
</svg>

<figure>
  <figcaption>Original</figcaption>
  <img src="http://www.placecage.com/c/500/200"/>
  </figure>
<figure>
  <figcaption>Half grayed</figcaption>
  <img class="desaturate" src="http://www.placecage.com/c/500/200"/>
</figure>

MDN 上的参考资料

于 2014-09-18T14:30:55.540 回答
2

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

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

于 2010-10-19T04:58:39.350 回答
2

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

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

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%);
}
于 2015-01-26T06:22:38.607 回答
2

这是 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);
    }
}
于 2013-11-08T20:00:35.007 回答
2

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

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

于 2012-05-16T10:56:05.223 回答
1

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

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

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

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

于 2013-06-18T13:01:16.567 回答
1

根据robertc 的回答

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

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 的一个检查以下链接:

于 2013-09-13T20:42:11.560 回答
0

对于 Firefox 中的灰度百分比,请使用饱和过滤器:(搜索“饱和”)

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"
于 2014-10-21T01:01:41.693 回答
0

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

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

于 2009-06-11T04:41:43.877 回答
0

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

于 2013-10-01T11:00:46.167 回答
0

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

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

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

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

于 2013-11-12T15:05:17.710 回答
-1

如果您或将来面临类似问题的其他人对 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);

?>
于 2010-10-16T00:56:41.560 回答