Reputation: 275
I've read the HSL to RGB algorithm in wikipedia. I understand it and can convert using it. However I came upon another algorithm here, and the math is "explained" here.
The algorithm is:
//H, S and L input range = 0 ÷ 1.0
//R, G and B output range = 0 ÷ 255
if ( S == 0 )
{
R = L * 255
G = L * 255
B = L * 255
}
else
{
if ( L < 0.5 ) var_2 = L * ( 1 + S )
else var_2 = ( L + S ) - ( S * L )
var_1 = 2 * L - var_2
R = 255 * Hue_2_RGB( var_1, var_2, H + ( 1 / 3 ) )
G = 255 * Hue_2_RGB( var_1, var_2, H )
B = 255 * Hue_2_RGB( var_1, var_2, H - ( 1 / 3 ) )
}
Hue_2_RGB( v1, v2, vH ) //Function Hue_2_RGB
{
if ( vH < 0 ) vH += 1
if( vH > 1 ) vH -= 1
if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH )
if ( ( 2 * vH ) < 1 ) return ( v2 )
if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6)
return ( v1 )
}
I've tried following the math but I can't figure it. How does it work?
Upvotes: 1
Views: 1389
Reputation: 464
If anyone would like a much simplified version, using 8bit integers rather than floats and using max colour intensity (L = 0.5, S = 1; meaning v1 = 0.0, v2 = 1.0) it might help to explain things.
void huetoRGB (const uint8_t hue, uint8_t *RGB) {
RGB[0] = hueconv(hue + 85); // R
RGB[1] = hueconv(hue); // G
RGB[2] = hueconv(hue - 85); // B
}
// 0 <= vH <= 255
uint8_t hueconv(int vH) {
if (vH < 0) vH += 256;
if (vH > 255) vH -= 256;
if (vH <= 42) return 6 * vH;
if (vH <= 127) return 255;
if (vH <= 170) return (170 - vH) * 6;
return 0;
}
Upvotes: 0
Reputation: 73444
The first part if ( S == 0 )
is for the case that there is no Saturation it means that it’s a shade of grey. You set the Luminance, set RGB to that grey scale level and you are done.
If this is not the case, then we need to perform the tricky part:
We shall use var_1
and var_2
as temporary values, only for making the code more readable.
So, if Luminance is smaller then 0.5 (50%) then var_2 = Luminance x (1.0 + Saturation. If Luminance is equal or larger then 0.5 (50%) then var_2 = Luminance + Saturation – Luminance x Saturation. That's the else part of:
if ( L < 0.5 ) var_2 = L * ( 1 + S )
else var_2 = ( L + S ) - ( S * L )
Then we do:
var1 = 2 x Luminance – var_2
which is going to be useful later.
Now we need another three temporary variables for each color channel, as far as Hue is conserned. For Red, we add 0.333 to it (H + (1/3)
in code), for Green we do nothing, and for Blue, we subtract 0.333 from it (H + (1/3)
). That temporaty value is called vH
(value Hue) in Hue_2_RGB()
.
Now each color channel will be treated separetely, thus the three function calls. There are four formulas that can be applied to a color channel. Every color channel should "use" only one formula.
Which one? It depends on the value of Hue (vH
).
By the way, the value of vH
must be normalized, thus if it's negative we add 1, or if it's greater than 1, we subtract 1 from it, so that vH lies in [0, 1].
For R = 255 * Hue_2_RGB( var_1, var_2, H + ( 1 / 3 ) )
, the Color Channel would be the Red, named R
in the code.
Upvotes: 1