I'm trying to use an SVG filter to offset and fill the shape with a specific color. To adjust the color I'm using <feColorMatrix>
. I understand the color matrix uses clamp values for color, so I calculated the clamp values by taking the R, G, B values (0-255) and divided them by 256.
The issue is, this produced a much lighter color. I then tried it with a simple 0.5 and then color picked the result. I would expect a value of rgb(128,128,128) #808080 or at least something close, but it came out as a shocking rgb(187,187,187) #bbbbbb.
<filter id="midgrey">
<feColorMatrix values="
0 0 0 0 0.5
0 0 0 0 0.5
0 0 0 0 0.5
0 0 0 1 0">
</feColorMatrix>
</filter>
Obviously there's some kind of conversion going on here. After a bit of testing, the conversion definitely appears non-linear – some kind of exponential remapping.
Question #1: Where is this defined in the specification? I looked and couldn't find anything other than a brief mention of filters using the sRGB color space. Is this the reason?
color-interpolation-filters has no affect for Filter Functions. Filter Functions must operate in the sRGB color space.
Question #2: How can I convert from RGB triplets to this color scale such that the resulting color matches in RGB space?
Question #3: Perhaps this is the wrong way to convert color with SVG filters. Is there a different way to flood-fill a shape with a specific color?
(Note, it would still be nice to have answers to all three questions, even if an answer is provided for just #3)
TIA!
So, firstly, don't believe everything you read in the specs - especially when they're not at least a Candidate Recommendation. That filter spec has been worked on for years and many things that are different than the SVG 1.1 spec have not been implemented.
In SVG 1.1 (the current cross browser baseline) - filters operate in the linearRGB space. From the SVG spec (15.1)
(‘color-interpolation-filters’ has an initial value of linearRGB
(187, 187, 187) is what happens when you do 50% in the linearRGB space and then measure the result using an sRGB eye-dropper. In order to over-ride it, you must put color-interpolation-filters="sRGB" in your filter element.
This is a perfectly fine way to convert colors. As Robert mentioned in the comment - you can also use a flood & a composite to do it.
<filter id="flood-recolor">
<feFlood flood-color="grey"/>
<feComposite operator="in" in2="SourceGraphic"/>
</filter>