使用 CSS 对图像进行着色而不叠加

Posted

技术标签:

【中文标题】使用 CSS 对图像进行着色而不叠加【英文标题】:Tint image using CSS without overlay 【发布时间】:2012-09-14 19:39:13 【问题描述】:

是否可以在 WebKit 浏览器中使用 CSS 将图像着色为特定颜色而无需覆盖?

尝试失败

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

想法

给定一种颜色,是否可以组合 HSB 滤镜(hue-rotatesaturationbrightness)来生成其色调?

【问题讨论】:

我想知道为什么棕褐色得到了皇室待遇。 我见过几个依赖画布和 javascript 的解决方案……这不太理想。 您在问题中打错了-webkit-filter。确认您没有在代码中输入相同的错字可能会很好? ;-) filter CSS 样式仅适用于 SVG,但现在它也将成为标准 html。我不确定哪些浏览器支持它,但如果它在您的目标浏览器中实现,那么您不需要为此使用 SVG;只需将样式直接应用于<img> HTML 标记即可。 (浏览器支持矩阵见caniuse.com/#feat=css-filters) @Spudley:已修复。不过,代码还可以。 【参考方案1】:

最终会使用着色器。请参阅有关过滤器的 W3C 文档。

目前,例如:

-webkit-filter: grayscale; /*sepia, hue-rotate, invert....*/
-webkit-filter: brightness(50%); 

David Walsh on CSS Filters ***: apply a rose tint...: W3C Filter Effects 1.0 Docs - 38.2.5. Other uniform variables: the CSS shaders parameters

更新

Adobe 发布了基于 HTML5 的 CSS Filter Labs,在支持的浏览器上支持 custom filters(着色器):

【讨论】:

着色器已被弃用 - 习惯使用过滤器!【参考方案2】:

虽然没有独立的色调过滤器,但您可以通过组合现有过滤器来制作一种不带阴影的过滤器。

结合棕褐色来统一颜色,然后色调旋转到你想要的颜色

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

我使用带有 alpha 值的边框作为我的色调,它实际上是一个叠加层,但不使用任何额外的 DOM 元素,从而在其他浏览器获得这些过滤器时更简单地过渡到棕褐色+hue-rotate。

【讨论】:

hue-rotate 几乎被破坏了——它在饱和颜色上的工作非常不准确——尤其是黄色,因为它实际上在 RGB 空间而不是真正的 HSL 空间中进行了非常差的近似。 除非我遗漏了什么,否则这在很大程度上不适用于黑白图像,因为棕褐色和色调旋转对白色影响不大。 @GrantBirchmeier brightness(50%); 将变成白色到灰色。【参考方案3】:

那么垫底怎么样?

HTML:

<span class="tint"><img src="..." /></span>

CSS:

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

根据需要调整颜色和不透明度。不适用于具有透明度的图像。

【讨论】:

【参考方案4】:

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

任何颜色的色调(而不是并非所有地方都支持的棕褐色或旋转滤镜)可以通过适当大小的插入框阴影来实现。

【讨论】:

请给你的答案添加一些解释! 如果这是你的答案,那应该是评论。 你去吧,希望它能让你开心 非常好!我正在寻找带有文字的东西;这种技术可以通过使用text-shadow 仅对文本的背面着色,然后应用一些透明的color.... 我疯了,还是这实际上没有给任何前景元素着色?根据 CSS3,嵌入阴影出现在内容下方,这意味着它们根本不会影响图像或文本,这正是我在实验页面中看到的。【参考方案5】:

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

<svg   viewbox="0 0 800 600">
    <defs>
        <filter id="f1" x="0%" y="0%"   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"   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/ 的动态演示

【讨论】:

为什么没有得到更多的支持? @Michael Mullany 有没有一种方法可以将十六进制颜色转换为矩阵值? 矩阵值在 0 到 1 的范围内 - 所以只需将您的十六进制值除以 255(或 FF)即可获得您想要的值。例如,如果你想要 100% 的红色,那么第一行将是 1 1 1 0 0。如果你想要 50% 的绿色,第二行将是 0.5 0.5 0.5 0 0 等等。 我知道前 4 列是 RGBA,但是……第 5 列是干什么用的? 第五列给颜色加上一个固定的总和。这是一个关于过滤器的几乎仍然准确的演示文稿的链接:slideshare.net/mullany1/svg-filters-html5-devconf-apr-2013。这是一个很久以后的答案 - 所以这就是为什么没有那么多赞成票的原因。此外,原来的答案现在已经过时/错误 - CSS 着色器已从网络路线图中删除

以上是关于使用 CSS 对图像进行着色而不叠加的主要内容,如果未能解决你的问题,请参考以下文章

带有CSS的图像灰度和鼠标悬停时重新着色?

如何用不同颜色为图像中的对象着色

如何将 CSS 自动应用于 console.log 着色[重复]

我如何在iOS上以编程方式为图像着色?

使用单行 CSS 对图像进行渐变叠加

OpenCV进阶基于OpenCV的图像着色