css - 使用 CSS 过滤器模拟 Photoshop 的 "Color Overlay"?

标签 css image-manipulation hsv color-space css-filters

我有一个图标,我想使用 CSS 更改其颜色。它位于 CSS 内联的数据 URI 优化 SVG 中。

通常,这是不可能的。这就是发明图标字体的原因;与 SVG 相比,它们的主要优势是能够从 CSS 接收 colortext-shadow 规则。嗯,CSS filters现在能够对任意图像执行这两种操作,并且 they now work in all Blink, Webkit and Gecko browsers , 和 can be expected for future IE/Spartan .

text-shadow 替换很容易;只需使用 drop-shadow filter .

然而,尽管所有必要的滤镜都已准备就绪,但事实证明,将图像着色为特定颜色非常棘手。到目前为止,我的理论如下:

  • 使用contrast(0)将整个图像变成纯灰色,同时保持 alpha channel (Mozilla wiki 说它会变成黑色,但在所有浏览器中它变成灰色,一定是打字错误)。
  • 使用sepia(1) ,因为我们不能对灰度图像的色相/饱和度进行操作。这确保了整个图像由我们可以进行数学运算的引用颜色组成;具体来说,#AC9977

此时,我们应该能够使用 hue-rotate 将整个图像从现在的纯色 #AC9977 变成我们想要的任何颜色。 , saturatebrightness .

首先,浏览器使用什么颜色坐标?我找不到 the spec 的意义确定它是否使用 HSL (Lightness) or HSV (Value) , 但由于 HSB (Brightness) 是 HSV 的另一个名称,我想它使用的是 HSV。此外,使用诸如 brightness(999) 之类的东西会使颜色饱和(而不是使它们变白),这会发生在 HSV 而不是 HSL 中。

基于这个假设,我们将进行如下操作:

  • 计算#AC9977 和我们想要的颜色之间的色相差,并使用hue-rotate .
  • 计算两者之间的饱和度差异,并使用saturate .
  • 计算两者之间的亮度差异,并使用brightness .

由于这不是手动完成的事情,我们将使用 LESS preprocessor :

.colorize(@color) {
    @sepiaGrey: #AC9977;
    @hOffset: (hsvhue(@color) - hsvhue(@sepiaGrey)) * 1deg;
    @sRatio: unit(hsvsaturation(@color) / hsvsaturation(@sepiaGrey));
    @vRatio: unit(hsvvalue(@color) / hsvvalue(@sepiaGrey));
    -webkit-filter: contrast(0) sepia(1) hue-rotate(@hOffset) saturate(@sRatio) brightness(@vRatio);
    filter: contrast(0) sepia(1) hue-rotate(@hOffset) saturate(@sRatio) brightness(@vRatio);
}

根据我的理解,这应该可行。 But it isn't . 为什么,以及如何让它发挥作用?

我想要达到的目标的例子

将图标视为图像或元素(背景图像、基于 CSS 的形状等),具有任何颜色,并具有由透明度定义的形状(不是 一个可以简单叠加的矩形图像)。我想让它完全由具有 CSS 的特定颜色组成(大概是使用 filters)。

example

我计划将其实现为 LESS mixin这需要一个颜色参数,但只需指导 HSB 函数背后的逻辑就足够了。

最佳答案

我有时会尝试实现您想要的,但没有成功。

无论如何你有一个替代方案,使用混合模式:

div {
    background-color: green;
    mix-blend-mode: color;
    position: absolute;
    width: 200px;
    height: 400px;
}
<div></div>
    <img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Hsl-hsv_models.svg/400px-Hsl-hsv_models.svg.png" height="400">

我错过了透明度要求。让我们再试一次 :-)。缺点:需要设置图片2次。

#test1 {
  background: linear-gradient(red, red), url("http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png");
  width: 100%;
  height: 500px;
  background-blend-mode: hue;
  -webkit-mask-image: url("http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png");
}

body {
  background-color: lightblue;
}
<div id="test1">
</div>

好的;假设想要的结果是:你有一个图像,它将充当一个面具。您想要使用此蒙版在现有图像上设置彩色叠加层,但您希望在 CSS 样式中指定颜色,以便轻松编辑。

如果您可以更改图像,以便使用的 channel 是亮度而不是 alpha,则以下示例可以作为您的解决方案 你需要一个灰色和黑色的滤镜,像这样

mask file

.test {
        width: 200px;
    height: 200px;
    display: inline-block;
    background-image: url(http://i.stack.imgur.com/kxKXy.png); 
    background-size: cover;
    background-blend-mode: exclusion;
    mix-blend-mode: hard-light;
}

.testred {
    background-color: red;
}

.testblue {
    background-color: blue;
}

body {
    background: repeating-linear-gradient(45deg, lightblue 0px, lightyellow 50px);
}
<div class="test testred"></div>
<div class="test testblue"></div>

关于css - 使用 CSS 过滤器模拟 Photoshop 的 "Color Overlay"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29458666/

相关文章:

python - 使用 python-numpy 放大图像

Java:检测颜色(例如我的颜色是蓝色吗?)

javascript - 在 Canvas 标签中移动和清除线条

javascript - 如何让div在按钮点击时淡入下面最近的div?

html - Bootstrap 'align-content-around' 不工作

c# - 如何从大字符串值创建多页 Tiff 文件

Python turtle 图章在 turtle 形状的图像处理后神秘消失

安卓颜色转换问题

python - 获取图像中的所有 R-G-B

HTML - 如果单击文本,自定义单选按钮不会切换