在这里聚会有点晚了,但我已经为您构建了一个 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);