Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A little late to the party here, but I've built you a CSS custom filter that does exactly what you're looking for. All the code can be found on GitHub here: <a href="https://github.com/awgreenblatt/css-custom-filters/tree/master/duotone" rel="nofollow">https://github.com/awgreenblatt/css-custom-filters/tree/master/duotone</a></p> <p>Because of security restrictions, custom filters can't read pixels; they can only apply transformations to them. So for instance, the filter can't say, if the pixel is black, change it to red. However, there is still a way to do it.</p> <p>Each color component ranges from [0,1]: All white pixels in the source image will be (1, 1, 1, 1) and all black pixels in the source image will be (0, 0, 0, 1)</p> <p>Let's call the color you want to map black to: (br, bg, bb, 1) and the color you want to map white to: (wr, wg, wb, 1)</p> <p>You can define in a fragment shader a css_ColorMatrix which will apply a transformation on the source image. If we set the blend mode to 'multiply' then the css_ColorMatrix will be pre-multiplied by the current source image's color.</p> <p>So, we set the css_ColorMatrix to:</p> <pre><code>wr - br, 0, 0, 0, 0, wg - bg, 0, 0, 0, 0, wb - bb, 0, br, bg, bb, 1 </code></pre> <p>If the source pixel is black, (0, 0, 0, 1) then the result of the multiplication will be (br, bg, bb, 1) If the source pixel is white (1, 1, 1, 1) then the result of the multiplication will be</p> <p>((wr - br + br), (wg - bg + bg), (wb - bb + bb), 1) or (wr, wg, wb, 1)</p> <p>Here's the fragment shader source:</p> <pre><code>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); } </code></pre> <p>The vertex shader is just the default:</p> <pre><code>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; } </code></pre> <p>And you apply the filter as follows:</p> <pre><code>-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); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload