<meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta content="utf-8" http-equiv="encoding"> <!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <style> .protanopia { -webkit-filter: url(#protanopia); -moz-filter: url(#protanopia); -ms-filter: url(#protanopia); -o-filter: url(#protanopia); filter: url(#protanopia); } .deuteranopia { -webkit-filter: url(#deuteranopia); -moz-filter: url(#deuteranopia); -ms-filter: url(#deuteranopia); -o-filter: url(#deuteranopia); filter: url(#deuteranopia); } .tritanopia { -webkit-filter: url(#tritanopia); -moz-filter: url(#tritanopia); -ms-filter: url(#tritanopia); -o-filter: url(#tritanopia); filter: url(#tritanopia); } </style> </head> <body> <!------------------------------------------------------------------- DaltonLens SVG filters to simulate color vision deficiencies https://daltonlens.org/opensource-cvd-simulation/ for a discussion of the various methods. The various matrices were generated from DaltonLens-Python. It is very important for these filters to get applied in linearRGB, which is supposed to be the default, but never hurts to specify it explicitly. --------------------------------------------------------------------> <svg style='height: 0; width: 0; padding: 0; margin: 0; line-height: 0;'> <!-- Single matrix approximation of Viénot, Brettel & Mollon 1999 --> <filter id="protanopia" color-interpolation-filters="linearRGB"> <feColorMatrix type="matrix" in="SourceGraphic" values=" 0.10889,0.89111,-0.00000,0,0 0.10889,0.89111,0.00000,0,0 0.00447,-0.00447,1.00000,0,0 0,0,0,1,0" /> </filter> <!-- Single matrix approximation of Viénot, Brettel & Mollon 1999 --> <filter id="deuteranopia" color-interpolation-filters="linearRGB"> <feColorMatrix type="matrix" in="SourceGraphic" values=" 0.29031,0.70969,-0.00000,0,0 0.29031,0.70969,-0.00000,0,0 -0.02197,0.02197,1.00000,0,0 0,0,0,1,0" /> </filter> <!-- Brettel, Viénot & Mollon 1997 algorithms with two projection planes. This is the only approach I know that is supposed to be reasonably accurate for tritanopia, the single matrix approaches are NOT accurate. --> <filter id="tritanopia" color-interpolation-filters="linearRGB"> <!-- Projection 1, with a special alpha that encodes the separation plane. If dot(rgb, n) > 0, then use projection 1, otherwise use projection 2. This is encoded in alpha by: - Applying a 1.0 factor on the source alpha so that 0 input alpha remains 0 - Subtracting 0.2 so that negative values become < 0.8 and position values >= 0.8 - It is important to normalize the factors to keep a good numerical accuracy and to keep a large alpha threshold since the RGB values are then stored premultiplied by alpha. - This assumes that negative values get clipped to 0, and positive values clipped to 1, without overflowing, etc. Which seems to be the case on all browsers. --> <feColorMatrix type="matrix" in="SourceGraphic" result="ProjectionOnPlane1" values=" 1.01354, 0.14268, -0.15622, 0, 0 -0.01181, 0.87561, 0.13619, 0, 0 0.07707, 0.81208, 0.11085, 0, 0 7.92482, -5.66475, -2.26007, 1, -0.2" /> <!-- Binarize alpha. 5 values means the last chunk will start at 0.8. All the values below 0.8 will become 0 (correspond to the dot product with the separation plane being negative) and above will become 1 --> <feComponentTransfer in="ProjectionOnPlane1" result="ProjectionOnPlane1"> <feFuncA type="discrete" tableValues="0 0 0 0 1"/> </feComponentTransfer> <feColorMatrix type="matrix" in="SourceGraphic" result="ProjectionOnPlane2" values=" 0.93337, 0.19999, -0.13336, 0, 0 0.05809, 0.82565, 0.11626, 0, 0 -0.37923, 1.13825, 0.24098, 0, 0 0,0,0,1,0" /> <!-- Uncomment the debug black matrix to see which pixels go to which plane --> <!-- <feColorMatrix type="matrix" in="SourceGraphic" result="ProjectionOnPlane2" values="0,0,0,0,0 0,0,0,0,0 0,0,0,0,0 0,0,0,1,0"/> --> <!-- Blend the two projections, picking one or the other depending on alpha. --> <feBlend in="ProjectionOnPlane1" in2="ProjectionOnPlane2" mode="normal"/> </filter> </svg> <!------------------------------------------------------------------> <h2>Normal</h2> <div class="normal"> <img src="https://daltonlens.org/images/rgbspan.png"> </div> <h2>Protanopia (Viénot, Brettel & Mollon 1999)</h2> <div class="protanopia"> <img src="https://daltonlens.org/images/rgbspan.png"> </div> <h2>Deuteranopia (Viénot, Brettel & Mollon 1999)</h2> <div class="deuteranopia"> <img src="https://daltonlens.org/images/rgbspan.png"> </div> <h2>Tritanopia (Brettel, Viénot & Mollon 1997)</h2> <div class="tritanopia"> <img src="https://daltonlens.org/images/rgbspan.png"> </div> </body> </html>