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

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

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

我知道我可以用SVG和Canvas来做,但现在看起来有很多工作要做。

真的有懒人能做到的方法吗?

473190 次浏览

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

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

虽然您不想使用Javascript,但我认为您必须使用它。您也可以使用服务器端语言来实现这一点。

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

然而,我确实发现这篇文章来自去年六月在HTML上使用了SVG过滤器。目前在任何浏览器中都无法使用(演示版本暗示了一个自定义WebKit构建),但作为概念的证明,它非常令人印象深刻。

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

如果你的用户正在使用尖端浏览器和如果 Firefox 3.5和Safari 4支持它(我不知道是否会),你可以调整图像的CSS 颜色配置文件属性,将其设置为灰度ICC配置文件URL。但那有很多假设!

如果你,或其他人在未来面临类似的问题是开放的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);


?>

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

所以我在谷歌上搜索“canvas grayscale”,第一个结果是http://www.permadi.com/tutorial/jsCanvasGrayscale/index.html,这似乎是可行的。

在Internet Explorer中使用filter属性。

在webkit和Firefox中,目前没有办法单独使用CSS来降低图像的饱和度。 所以你将需要使用canvas或SVG作为客户端解决方案 但是我认为使用SVG更优雅。看看我的博客文章,SVG解决方案,同时适用于Firefox和webkit: # EYZ0 < / p >

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

brillout.com的回答罗曼·努里克的回答开始,稍微放宽了“无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专有的,应用这个类到任何图像,你想转换为灰度(工作在Firefox >3.5, IE8)

编辑: 这是一篇不错的博客文章,它描述了在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 */
}

# EYZ0。

如果您能够使用JavaScript,那么这个脚本可能就是您正在寻找的。它跨浏览器工作,目前为止对我来说工作得很好。您不能将它用于从不同域加载的图像。

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

所以我们现在有了一个跨浏览器的解决方案。

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


What about Internet Explorer 10?

You can use a polyfill like gray.

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

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

webkit中对本地CSS过滤器的支持已从当前版本19.0.1084.46添加

所以-webkit-filter:灰度(1)将工作,这是更容易为webkit的SVG方法…

我把它做成了一个完整的GitHub repo,包括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%);
}

对于Firefox,您不需要创建filter.svg文件,您可以使用数据URI方案

第一个答案的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请求。

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

旧浏览器的替代方案可以是使用伪元素或内联标签产生的掩码。

绝对定位悬停在一个img(或文本区域,不需要点击或选择)可以很好地模仿颜色比例的效果,通过rgba()或透射PNG

它不会给出一个单一的颜色尺度,但会将颜色的阴影超出范围。

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

基于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(红-绿-蓝-alpha)模型的所有类型的图像都可以正常工作。

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

你可以使用jFunc的一个函数-使用函数"jFunc_CanvasFilterGrayscale" # EYZ0 < / p >

下面是一个用于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);
}
}

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

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

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

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

作为对其他人的回答的补充,在FF上降低图像饱和度是有可能的,而没有SVG的矩阵的头痛:

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

其中$v介于01之间。它等价于filter: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上的引用

对于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"

你不需要使用那么多的前缀来充分使用,因为如果你为旧的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%);
}

一种新的方法已经在现代浏览器上出现了一段时间了。

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

光度,设置在白色背景上,允许它。 (悬停看到灰色)

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

The luminosity is taken from the image, the color is taken from the background. Since it is always white, there is no color.

But it allows much more.

You can animate the effect setting 3 layers. The first one will be the image, and the second will be a white-black gradient. If you apply a multiply blend mode on this, you will get a white result as before on the white part, but the original image on the black part (multiply by white gives white, multiplying by black has no effect.)

On the white part of the gradient, you get the same effect as before. On the black part of the gradient, you are blending the image over itself, and the result is the unmodified image.

Now, all that is needed is to move the gradient to get this effect dynamic: (hover to see it in color)

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>

reference

compatibility matrix

也许这样能帮到你

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

w3schools.org

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

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

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