Sometimes when working with bitmaps you might find the need to work in a HSL (Hue, Saturation, Luminance) mode, for example when trying to detect skintones in an image. So what you do is probably to use the classic formula from Wikipedia that uses min/max and a whole lot of ifs: http://en.wikipedia.org/wiki/HSL_and_HSV
Well, here is a little alternative method: whilst working with the YUV colorspace I figured that since Y contains all the luminance information, the U + V channels must thus contain the hue and saturation. And it turns out that indeed when looking at u and v as the coordinates of a vector, its angle will represent the hue and its length will be the saturation.
So a formula that does not need any min/max and ifs to convert rgb to hsl looks like this:
// r,b and b are assumed to be in the range 0...1 luminance = r * 0.299 + g * 0.587 + b * 0.114; u = - r * 0.1471376975169300226 - g * 0.2888623024830699774 + b * 0.436; v = r * 0.615 - g * 0.514985734664764622 - b * 0.100014265335235378; hue = atan( v, u ); saturation = Math.sqrt( u*u + v*v );
In this case hue will be between -Pi and Pi and saturation will be between 0 and 1/sqrt(2), so you might want to multiply the saturation by sqrt(2) to get it in a range between 0 and 1.
Of course this also works the other way round - hsl to rgb looks like this:
// hue is an angle in radians (-Pi...Pi) // for saturation the range 0...1/sqrt(2) equals 0% ... 100% // luminance is in the range 0...1 u = cos( hue ) * saturation; v = sin( hue ) * saturation; r = luminance + 1.139837398373983740 * v; g = luminance - 0.3946517043589703515 * u - 0.5805986066674976801 * v; b = luminance + 2.03211091743119266 * u;
[Edit]As it was correctly noticed in the comments, the values that this method returns are not the HSL values that you get when you are using the classic formula. Nevertheless I think that this method has its uses, for example if you want to quickly create color schemes or if you are using it like in the demo to change the hue/saturation/Luminance of a photo.[/Edit]
[Edit]I updated the factors in the matrix one more time with values I found in the Wikipedia YUV discussion page. Those look better to me at least.