用ColorMatrix CSS滤镜将黑白图片转换为双色调。

4
我需要创建一个自定义的CSS过滤器,将黑白图像转换为两种自定义颜色的双色图像。
我想以这种方式应用过滤器(不确定是否可能使用此语法,可能必须单独传递6个参数):
.duotone {
    -webkit-filter: custom(none url(/filters/duotone.fs),
        black_color [255, 0, 0] white_color [255, 192, 203]);
}

在这种情况下,将黑色替换为红色,白色和透明颜色(背景)都替换为粉色,所有灰色的色调都用直线曲线之间的颜色替换。也许甚至可以在CSS中定义过滤器而不需要外部文件?该过滤器的应用是在运行时将黑白图标转换为彩色图标。关于如何实现此功能的示例很少,this one非常通用,涵盖了更广泛的过滤器范围,specification 也不太容易理解。是否有人可以发布一个可行的过滤器来做到这一点或类似的事情?或者至少,您可以指向一些与我的情况相关的更专注的ColorMatrix应用示例吗?

1
哇,我没想到 WebKit 过滤器那么先进(你可以像在 WebGL 中定义着色器一样定义)。看起来你可以将每个颜色映射到 [0,1] 中的值,然后将这些值映射到任意的渐变,尽管渐变越复杂,出现奇怪的伪影的可能性就越大。不管怎样,听起来你想要的是可行的;如果没有人首先回答一个由着色器明确定义的工作解决方案,也许我会试试运气(但今晚不行)。 - JayC
我也认为这是可行的,实际上我想要的甚至更简单。由于我的图像是黑色/透明(掩模),我只需要将黑色和灰色移动到另一种颜色及其阴影中,白色可以保持不变。请参见下面答案的评论... - esp
2个回答

3

更新:

为了实现这一点,您需要在CSS中使用-webkit-mask-image。这曾经是仅限于webkit的,但现在是w3c css3。

支持只存在于webkit上。为了保持向后兼容性并显示常规的黑色图标,您需要确定浏览器是否具有此功能。我使用modernizr来实现这一点。

http://jsfiddle.net/kkobold/Zq5FZ/5/

旧答案:

I believe thats the result you are looking for:

http://s7.postimage.org/vo5v33tuj/Screen_Shot_2013_02_03_at_11_28_46_PM.png

you can archive it by filtering to sepia and then changing hue degree. different combinations will give different results. But a simple color picker can be made for the hue and a slide for sepia to increase or decrease intensity of the color change.

and CSS3 only.

<div class="pull-left span4" >
<img src="/img/bw.jpg" style="-webkit-filter: sepia(0.0) hue-rotate(0deg);" width="300"/><br />
-webkit-filter: sepia(0) hue-rotate(0deg);
</div>
<div class="pull-left span4" >
<img src="/img/bw.jpg" style="-webkit-filter: sepia(0.8) hue-rotate(50deg);" width="300"/><br />
-webkit-filter: sepia(0.8) hue-rotate(50deg);
</div>
<div class="pull-left span4" >
<img src="/img/bw.jpg" style="-webkit-filter: sepia(0.8) hue-rotate(100deg);" width="300"/><br />
-webkit-filter: sepia(0.8) hue-rotate(100deg);
</div>
<div class="pull-left span4" >
<img src="/img/bw.jpg" style="-webkit-filter: sepia(0.8) hue-rotate(150deg);" width="300"/><br />
-webkit-filter: sepia(0.8) hue-rotate(150deg);
</div>
<div class="pull-left span4" >
<img src="/img/bw.jpg" style="-webkit-filter: sepia(0.8) hue-rotate(200deg);" width="300"/><br />
-webkit-filter: sepia(0.8) hue-rotate(200deg);
</div>
<div class="pull-left span4" >
<img src="/img/bw.jpg" style="-webkit-filter: sepia(0.8) hue-rotate(250deg);" width="300"/><br />
-webkit-filter: sepia(0.8) hue-rotate(250deg);
</div>
<div class="pull-left span4" >
<img src="/img/bw.jpg" style="-webkit-filter: sepia(0.8) hue-rotate(300deg);" width="300"/><br />
-webkit-filter: sepia(0.8) hue-rotate(300deg);
</div>
<div class="pull-left span4" >
<img src="/img/bw.jpg" style="-webkit-filter: sepia(0.8) hue-rotate(350deg);" width="300"/><br />
-webkit-filter: sepia(0.8) hue-rotate(350deg);
</div>

1
谢谢。我会再次研究一下棕褐色滤镜。虽然它似乎是一个非常不同的滤镜。棕褐色不改变黑白,黑色仍然是黑色,白色仍然是白色,在棕褐色之后,灰色变成了彩色。我需要一个滤镜,将100%的黑色转换为我选择的一种颜色,将100%的白色转换为另一种颜色,并在这个转换中这两种颜色之间有直线。用法如下-我有一个黑白图标,我希望它变成例如粉红色背景上的红色图标。我不认为我可以“滥用”棕褐色来实现它 :) - esp
1
这是你想要的吗?http://jsfiddle.net/WHWnp/. 只需更改.dashboard-buttons .sessions .img的背景颜色,图标颜色就会改变。 - Danilo Kobold
1
谢谢,这正是我需要的。我花了很多时间搜索,但我不知道它叫什么...但这种方法的问题是,如果不支持掩码,它将不显示任何内容,而我更希望它显示黑白图像-自定义过滤器可以完全实现这一点。由于图像实际上不是黑白而是黑色和透明的,所以它会在我需要的背景上显示黑色。因此,至少我需要一个过滤器来改变黑色,我们可以保留白色不变... - esp
这是一种更复杂的方法,使用SVG https://dev59.com/S2ct5IYBdhLWcg3wmOZN另一个解决方案是使用modernizr(http://modernizr.com/)来测试是否可用mask-filter,如果不可用,则添加一个类以实现向后兼容。 mask-image是w3c,因此它可能最终会出现。 - Danilo Kobold
1
谢谢。抱歉,这周太忙了。我可能会像你建议的那样使用遮罩和黑色图像作为备选方案,SVG 太复杂了... - esp

3
我有点晚了,但我为您构建了一个CSS自定义过滤器,可以完全满足您的需求。所有的代码都可以在GitHub上找到:https://github.com/awgreenblatt/css-custom-filters/tree/master/duotone 由于安全限制,自定义过滤器不能读取像素;它们只能对像素应用变换。因此,例如,该过滤器无法说,如果像素是黑色的,则将其更改为红色。但是,仍然有一种方法可以做到这一点。
每个颜色分量范围为[0,1]:源图像中的所有白色像素将是(1, 1, 1, 1),而所有黑色像素将是(0, 0, 0, 1)。
假设您想要映射黑色的颜色是(br, bg, bb, 1),白色的颜色是(wr, wg, wb, 1)
您可以在片段着色器中定义一个css_ColorMatrix,它将对源图像应用变换。如果我们将混合模式设置为“乘法”,那么css_ColorMatrix将与当前源图像的颜色进行预乘。
因此,我们将css_ColorMatrix设置为:
wr - br,       0,       0,     0,
      0, wg - bg,       0,     0,
      0,       0, wb - bb,     0,
     br,      bg,      bb,     1

如果源像素为黑色(0、0、0、1),那么乘法的结果将是(br、bg、bb、1)。 如果源像素为白色(1、1、1、1),则乘法的结果将是 ((wr - br + br),(wg - bg + bg),(wb - bb + bb),1) 或者 (wr,wg,wb,1)
以下是片段着色器源代码:
precision mediump float;

uniform vec3 black;
uniform vec3 white;

// Main

void main()
{
  vec3 b = black / 255.0;
  vec3 w = white / 255.0;

  css_ColorMatrix = mat4(w.r-b.r, 0.0, 0.0, 0.0,
                         0.0, w.g - b.g, 0.0, 0.0,
                         0.0, 0.0, w.b - b.b, 0.0,
                         b.r, b.g, b.b, 1.0);
}

顶点着色器只是默认值:
precision mediump float;

// Built-in attributes

attribute vec4 a_position;

// Built-in uniforms

uniform mat4 u_projectionMatrix;

// Main

void main()
{
  gl_Position = u_projectionMatrix * a_position;
}

您可以按照以下方式应用过滤器:

-webkit-filter: custom(url(duotone.vs) mix(url(duotone.fs) normal source-atop), 
             1 1 border-box, black 255 0 0, white 255 192 203);

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