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

时间:2009-03-04 04:51:27

标签: css image css3 grayscale

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

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

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

是否有一个真正懒惰的人这样做?

26 个答案:

答案 0 :(得分:697)

Support for CSS filters has landed in 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="http://lorempixel.com/400/200/">


Internet Explorer 10怎么样?

您可以使用gray之类的polyfill。

答案 1 :(得分:126)

继续brillout.com's answer以及Roman 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)

编辑Here'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

答案 2 :(得分: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请求。

答案 3 :(得分:26)

更新:我将其变成了一个完整的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%);
}

答案 4 :(得分:14)

如果您能够使用JavaScript,那么此脚本可能就是您要查找的内容。它适用于跨浏览器,到目前为止对我来说工作正常。您不能将其用于从其他域加载的图像。

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

答案 5 :(得分:11)

今天遇到同样的问题。我最初使用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不再支持标准兼容模式中的“filter:gray:”,因此需要在标头中使用兼容模式切换才能工作:

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

答案 6 :(得分:10)

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

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

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

答案 7 :(得分:7)

即使使用CSS3或专有的-webkit--moz- CSS属性,也看起来不太可能。

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

答案 8 :(得分: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 Graphics section和此旧IE博客http://blogs.msdn.com/b/ie/archive/2011/10/14/svg-filter-effects-in-ie10.aspx

答案 9 :(得分:7)

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

在webkit和Firefox中,目前没有办法仅使用CSS来破坏图像。 因此,您需要使用canvas或SVG作为客户端解决方案。

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

严格来说,由于SVG是HTML,解决方案是纯html + css: - )

答案 10 :(得分:6)

现代浏览器已经出现了一种新的方法。

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

在白色背景上设置的值 luminosity 允许它。 (将鼠标悬停在灰色中看)

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

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

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

但它允许更多。

您可以为效果设置设置3层动画。第一个是图像,第二个是白黑色渐变。如果对此应用多重混合模式,您将获得白色部分上的白色结果,但黑色部分上的原始图像(乘以白色会产生白色,乘以黑色无效。)

在渐变的白色部分,您可以获得与之前相同的效果。在渐变的黑色部分,您将图像混合在自身上,结果是未修改的图像。

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

&#13;
&#13;
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;
}
&#13;
<div class="test"></div>
&#13;
&#13;
&#13;

reference

compatibility matrix

答案 11 :(得分:4)

也许这样可以帮助你

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

w3schools.org

答案 12 :(得分:3)

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

答案 13 :(得分:3)

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

中的FILTER: Gray

Ax的方法只是使图像透明,背后有黑色背景。我相信你可以说这是灰度。

虽然您不想使用Javascript,但我认为您必须使用它。您也可以使用服务器端语言来完成它。

答案 14 :(得分: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);
    }
}

答案 15 :(得分:2)

您不需要使用这么多前缀来充分使用,因为如果您为旧版Firefox选择前缀,则不需要为新的Firefox使用前缀。

因此,为了充分利用,请充分使用此代码:

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%);
}

答案 16 :(得分:2)

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

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

答案 17 :(得分:2)

从当前版本19.0.1084.46

添加了对webkit中的本机CSS过滤器的支持

so -webkit-filter:grayscale(1)可以工作,哪个比webkit的SVG方法更容易...

答案 18 :(得分:1)

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

答案 19 :(得分:1)

作为对其他答案的补充,如果没有SVG的矩阵的头痛,可以在FF的一半去饱和图像:<\ n \ n / p>

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

$v位于01之间的位置。它相当于filter:grayscale(50%);

实例:

&#13;
&#13;
.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";
}
&#13;
<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>
&#13;
&#13;
&#13;

Reference on MDN

答案 20 :(得分:0)

你可以使用jFunc的一个功能 - 使用函数“jFunc_CanvasFilterGrayscale” http://jfunc.com/jFunc-functions.aspx

答案 21 :(得分:0)

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

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

有一个互动demo。你可以玩它。

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

答案 22 :(得分:0)

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

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"

答案 23 :(得分:0)

旧版浏览器的替代方法可能是使用伪元素或内联标记生成的掩码。

绝对定位悬停img(或者不需要点击或选择的文本区域)可以通过rgba()或translucide png 来密切模仿色标的影响,

它不会给出一个单一的色标,但会使色彩偏离范围。

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

答案 24 :(得分:0)

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

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

答案 25 :(得分:0)

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

?>