

Transformation to HSL/HSV (Re: SVG Filters 2)

From: Jasper van de Gronde <th.v.d.gronde@hccnet.nl>
Date: Mon, 31 May 2010 19:37:32 +0200
Message-ID: <4C03F3DC.1070105@hccnet.nl>
To: Hans Schmucker <hansschmucker@gmail.com>
CC: www-svg@w3.org
Hans Schmucker wrote:
>> Very good point (I've in fact done some work on converting to HSV/HSL and
>> back in SVG filters). And frankly I wouldn't mind support for arbitrary
>> numbers of (named?) channels.
> This is entirely off-topic, but is the code available somewhere? I've
> been trying to get HSI working, but the saturation needs a few
> operations that I'm just unable to emulate.

See the filters attached to this mail. I was supposed to get these 
on-line somewhere (almost a year ago), but I forgot I even had them 
until this mail.

The original explanation I sent to the Inkscape devel list (almost a 
year ago) with the explanation of this approach:
I couldn't help myself and had a look at HSL on Wikipedia 
I think it shouldn't be too hard:

First of all, let's assume tR, tG and tB (collectively called tC) are 
given (if only the target hue is given you could still compute them 
yourself with a little effort).

Now note what happens if you collapse the conversion from RGB to HSL and 
from HSL back to RGB:

l = (max+min)/2
if l<.5
   s = (max-min)/2l
   q = l*(1+s)
     = l + (max-min)/2
     = max/2 + min/2 + max/2 - min/2
     = max
   s = (max-min)/(2-2l)
   q = l + s - l*s
     = l + s*(1-l)
     = l + (max-min)/2
     = max
p = 2*l - q
   = max + min - max
   = min

Clearly, if we can compute the minimum and maximum of the RGB values the 
only thing left is to correctly combine these values using tC. Computing 
the minimum and maximum can be done using feBlend with darken/lighten if 
you first create three images with the original red, green and blue 
channels all in the same color(!) component (alpha set to 1?). You may 
want to make sure the values are replicated in all three color channels 
either beforehand or afterwards. (feColorMatrix is very useful for these 
kinds of operations)

This only leaves the question of computing the final color values. I 
would be inclined to use feFlood to get the tC values at every pixel and 
then use feComponentTransfer to determine the right coefficient for 
combining p/min and q/max (you could even flood with the hue and skip 
computing the tC values altogether). For the final blend you could use 
any number of methods to combine p and q. The nicest method would 
probably be if you would be able to directly get the coefficient into 
the alpha channel of q and then use simple alpha compositing (feBlend 
normal for example).

The main problem with all of the above is that it doesn't preserve the 
alpha channel. This is mainly because of having to compute the minimum 
and maximum, which uses normal alpha compositing for the alpha channel, 
making it quite inconvenient to use any alpha value other than 1 (and 
which definitely does NOT preserve the original alpha value). I think 
the easiest way out would probably be to post-multiply (using 
feComposite) the output with an image that has the alpha channel of the 
original image and all ones in the color channels (again feColorMatrix 
could come in handy).

I started creating something in Inkscape itself, but found that there is 
apparently a (at least one) bug in setting the blend mode. You should be 
able to create a file manually though.

Received on Monday, 31 May 2010 17:38:04 GMT
