是否有一个简单的方法来显示一个彩色位图的灰度与只是HTML/CSS?

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

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

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


当前回答

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

亮度和色差信号 马格斯的回答:“colorvalue中的greyscalevalue”@stackoverflow部分:编辑2:@Hans Passant Charles A. Bouman -普渡大学-模拟电视第20和21页 在这里你可以找到一些c#和VB代码

其他回答

更新:我把它做成了一个完整的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%);
}

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

如果您或其他将来面临类似问题的人愿意使用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,似乎可以。

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

背景混合模式可以让你得到一些有趣的效果,其中之一是灰度转换

设置在白色背景上的luminosity值允许这样做。 (鼠标悬停,灰色显示)

test { 宽度:300 px; 身高:200 px; 背景:url(“http://placekitten.com/1000/750”),白色; background-size:封面; } test:{徘徊 background-blend-mode:光度; } < div class = "测试" > < / div >

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

但它允许更多。

你可以将效果设置为3层。第一个是图像,第二个是黑白渐变。如果你应用混合模式,你会得到一个白色的结果,就像之前在白色部分,但原始图像在黑色部分(乘白色得到白色,乘黑色没有效果)。

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

现在,所有需要做的就是移动渐变来获得动态效果:(悬停可以看到颜色)

div { 宽度:600 px; 身高:400 px; } test { 背景:url(“http://placekitten.com/1000/750”), 线性渐变(0deg,白色33%,黑色66%),url(“http://placekitten.com/1000/750”); 背景-位置:0px 0px 0% 0px 0px; 背景尺寸:覆盖,100% 300%,覆盖; 背景-混合模式:亮度,倍增; 过渡:全部为2s; } test:{徘徊 背景位置:0px 0px, 0px 66%, 0px 0px; } < div class = "测试" > < / div >

参考

兼容性矩阵