# 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>

```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
(http://en.wikipedia.org/w/index.php?title=HSL_and_HSV&oldid=304926444).
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
else
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 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 8 March 2017 09:47:21 UTC