使用CSS对图像进行着色而无需叠加。

37

在WebKit浏览器中,是否可以使用CSS将图像染上特定颜色而无需叠加层?

失败的尝试

  • 使用hue-rotate可以将图像染成棕褐色或任意颜色,但找不到一种方法来用特定颜色染色。
  • 创建一个“tint”SVG过滤器,并使用-webkit-filter: url(#tint)调用它,在Chrome上不起作用。
  • 所有opacity/box-shadow CSS属性与drop-shadow/opacity过滤器的可能组合都不能产生所需的效果。

想法

  • 给定一个颜色,使用HSB过滤器(hue-rotatesaturationbrightness)进行组合,生成其带色。

20
我想知道为什么棕褐色被如此崇尚。 - hpique
我见过几种解决方案,它们依赖于一个画布和JavaScript来实现这一点...这远非理想。 - Lorenz Lo Sauer
在问题中,您的-webkit-filter有一个错别字。最好确认您的代码中没有犯同样的错误;-) - Spudley
filter CSS 样式最初只用于 SVG,但现在也适用于标准 HTML。我不确定哪些浏览器已经支持它,但如果您的目标浏览器已经实现了它,那么您就不需要再使用 SVG,直接将样式应用于 <img> HTML 标签即可。(请参见 http://caniuse.com/#feat=css-filters 以获取浏览器支持矩阵) - Spudley
@hpique:通过Adobe FilterLabs、Chrome Canary Builds和git社区的支持,你可能只需要几个小时就能得到一个可用的解决方案... - Lorenz Lo Sauer
来自Adobe的Rik Cabanier(我想)似乎是第一个提出具体CSS滤镜简写的人(并非所有这些都被采纳)。http://lists.w3.org/Archives/Public/public-fx/2011JanMar/0107.html - Michael Mullany
5个回答

26

着色器已被弃用 - 适应使用滤镜吧! - Michael Mullany

20

虽然没有独立的色调滤镜,但您可以通过组合现有的滤镜来制作一种类似于色调滤镜的效果,而不需要使用遮蔽。

将棕褐色滤镜与色相旋转滤镜结合起来,以统一颜色,并使其呈现出您想要的色调。

-webkit-filter: sepia(90%) hue-rotate(90deg);

我对我的色调使用带有透明度的边框,实际上这是一个叠加层,但不使用任何额外的DOM元素,使得当其他浏览器获得那些过滤器时,转换为棕褐色+色相旋转变得更简单。


hue-rotate 功能基本上是有问题的 - 它在饱和颜色方面做得非常不准确,特别是黄色,因为它实际上在 RGB 空间中进行了相当差的近似,而不是真正的 HSL 空间。 - Michael Mullany
除非我漏掉了什么,否则这在白底黑字的图像上基本不起作用,因为棕褐色和色相旋转对白色影响不大。 - Grant Birchmeier
1
@GrantBirchmeier brightness(50%); 将白色变为灰色。 - GKFX

19

现在可以使用SVG过滤器来实现,而无需使用着色器。您可以通过-webkit-filter:“url(#yourfilterID)”等语法将其用作CSS过滤器(尽管它在IE中不起作用)。

<svg width="800px" height="600px" viewbox="0 0 800 600">
    <defs>
        <filter id="f1" x="0%" y="0%" width="100%" height="100%" color-interpolation-filters="sRGB">
        <feColorMatrix id="tinter" type="matrix" values=".6 .6 .6 0 0 
                                                            .2 .2 .2 0 0 
                                                            .0 .0 .0 0 0 
                                                             0    0   0 1 0"/>
        </filter>     
    </defs>

 <image x="0" y="0" width="550" height="370" preserveAspectRatio="true"
    filter="url(#tinter)" xlink:href="http://www.crossfitwaxahachie.com/wp-content/uploads/2012/04/IMG_0752.jpg"/>
</svg>

动态演示请见http://codepen.io/mullany/details/baLkH/


2
为什么这个问题没有得到更多的赞?@Michael Mullany,您知道将十六进制颜色转换为矩阵值的方法吗? - dopatraman
2
矩阵的值是在0到1的范围内 - 所以只需将十六进制值除以255(或FF),就可以获得所需的值。例如,如果您想要100%的红色,则第一行将是1 1 1 0 0。如果您想要50%的绿色,则第二行将是0.5 0.5 0.5 0 0等等。 - Michael Mullany
我知道前四列是RGBA,但是第五列是用来做什么的? - dopatraman
1
第五列会给颜色添加一个固定的总和。这里有一个关于滤镜的幻灯片链接,基本上仍然准确:http://www.slideshare.net/mullany1/svg-filters-html5-devconf-apr-2013。这是一个更晚的答案 - 所以没有那么多赞。此外,原始答案现在已经过时/错误 - CSS着色器已从Web路线图中删除。 - Michael Mullany

13
box-shadow: inset 0px 0px 64px 64px cornflowerblue, 0px 0px 4px 4px cornflowerblue;

通过适当大小的内部阴影,可以实现任何颜色的着色(而不是不被所有地方支持的棕褐色或旋转过滤器)。


4
请仅翻译文本内容:请在您的回答中添加一些解释! - ρss
非常好!我正在寻找一些文本相关的东西;这种技术可以通过使用 text-shadow 仅对文本背景进行着色,然后只需应用一些透明的 color 即可应用于文本。 - kbtz
4
我疯了还是这并没有使任何前景元素变色?根据CSS3的规定,内嵌阴影出现在内容下方,这意味着它们根本不影响图像或文本,这正是我在我的实验页面中看到的。 - Grant Birchmeier
这是一个不错的技巧。实际上,它只适用于背景,不会改变前景。(但对我的需求来说已经足够了。)可以使用rgba语法设置半透明颜色:box-shadow: 0 0 0 9999px rgba(255, 0, 0, 0.25) inset; - Denilson Sá Maia

7
那么加一层底部怎么样?
HTML:
<span class="tint"><img src="..." /></span>

CSS:

.tint { background-color:red; display:inline-block; }
.tint img { opacity:0.8 }

根据您的需要调整颜色和不透明度。对于带有透明度的图像效果不佳。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接