有没有一种简单的方法可以仅使用 HTML/CSS
以灰度显示彩色位图?
它不需要与 IE 兼容(我想它不会)——如果它在 FF3 和/或 Sf3 中工作,那对我来说已经足够了。
我知道我可以同时使用 SVG
和 Canvas,但现在这似乎需要做很多工作。
有没有真正懒人的方法来做到这一点?
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。
继 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)。
edit: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。
-webkit-filter: grayscale(100%);
然后这个:-webkit-filter: grayscale(0);
删除它。
对于 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 请求。
更新:我把它做成了一个完整的 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%);
}
仅使用 CSS 实现灰度的最简单方法是通过 filter
属性。
img {
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
该属性仍未得到完全支持,并且仍然需要 -webkit-filter
属性才能在所有浏览器中提供支持。
如果您能够使用 JavaScript,那么此脚本可能就是您正在寻找的。它可以跨浏览器工作,到目前为止对我来说工作正常。您不能将它与从不同域加载的图像一起使用。
http://james.padolsey.com/demos/grayscale/
今天刚遇到同样的问题。我最初使用 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" />
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");
一段时间以来,现代浏览器上已经有一种新的方法可以做到这一点。
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; }
img
标记而不是 background: url()
,您如何应用它?
即使使用 CSS3 或专有 -webkit-
或 -moz-
CSS 属性,看起来也不可能(目前)。
但是,我确实发现 this post from last June 在 HTML 上使用了 SVG 过滤器。在任何当前浏览器中都不可用(演示暗示了自定义 WebKit 构建),但作为概念证明非常令人印象深刻。
对于在其他答案中询问被忽略的 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("#filtersPicture")" 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
在 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 :-)
也许这种方式可以帮助你
img {
-webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
filter: grayscale(100%);
}
如果我记得正确使用专有的 CSS 属性,实际上使用 IE 更容易做到这一点。试试这个来自 http://www.ssi-developer.net/css/visual-filters.shtml 的 FILTER: Gray
Ax 的方法只是使图像透明并在其后有黑色背景。我敢肯定你会说这是灰度。
尽管您不想使用 Javascript,但我认为您必须使用它。您也可以使用服务器端语言来做到这一点。
filter: gray
就出现在 Internet Explorer 中。他们为他们的产品做了很多废话——没错! - 但他们在这些东西上真的超前了
如果您愿意使用 Javascript,那么您可以使用画布将图像转换为灰度。由于 Firefox 和 Safari 支持 <canvas>
,它应该可以工作。
所以我用谷歌搜索了“canvas grayscale”,第一个结果是http://www.permadi.com/tutorial/jsCanvasGrayscale/index.html,它似乎有效。
从当前版本 19.0.1084.46 添加了对 webkit 中原生 CSS 过滤器的支持
所以 -webkit-filter: grayscale(1) 会起作用,这比 webkit 的 SVG 方法更容易......
这是 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);
}
}
你不需要使用这么多前缀来充分使用,因为如果你为旧的火狐选择前缀,你不需要为新的火狐使用前缀。
所以为了充分利用,足够使用这个代码:
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%);
}
作为对其他答案的补充,可以在 FF 上对图像进行一半去饱和,而无需 SVG 矩阵的头痛:
<feColorMatrix type="saturate" values="$v" />
其中 $v
在 0
和 1
之间。它相当于 filter:grayscale(50%);
。
现场示例:
.desaturate { filter: url("#desaturate"); -webkit-filter:灰度(50%); } figcaption{ 背景:rgba(55, 55, 136, 1);填充:4px 98px 0 18px;白颜色;显示:内联块;边框左上角半径:8px;边框右上角半径:100%;字体系列:“Helvetica”; }
是旧浏览器的另一种选择是使用由伪元素或内联标签产生的掩码。
通过 rgba() 或 translucide png 将绝对定位悬停在 img (或无需单击或选择的文本区域)可以密切模仿色标的效果。
它不会给出一个单一的色阶,但会使颜色超出范围。
通过伪元素用 10 种不同颜色的代码笔测试,最后是灰色。 http://codepen.io/gcyrillus/pen/nqpDd(重新加载以切换到另一张图片)
基于 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.2126 0.7152 0.0722 0 0
似乎等同于 <fecolormatrix type="saturate" values="0">
一个糟糕但可行的解决方案:使用 Flash 对象渲染图像,然后为您提供 Flash 中所有可能的转换。
如果您的用户正在使用最先进的浏览器并且 Firefox 3.5 和 Safari 4 支持它(我不知道是否会这样做),您可以调整图像的 CSS 颜色配置文件属性,将其设置为灰度 ICC个人资料网址。但这是很多如果的!
对于 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"
如果您或将来面临类似问题的其他人对 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);
?>