There seems to be 5 flavours of the “HSL”:
- HSL: Hue, Saturation, Lightness
- HSL: Hue, Saturation, Luminance
- HSV: Hue, Saturation, Value
- HSB: Hue, Saturation, Brightness
- HSI: Hue, Saturation, Intensity
I don’t understand why there are so many variants. I like RGB.
I needed a way to convert HSL (the luminance version) to RGB. Now .NET doesn’t have a way to convert any of the variants to its built-in System.Drawing.Color structure. Although the structure offers the GetHue(), GetSaturation() and GetBrightness() functions.
Generally speaking, the hue is between 0 and 360 degrees of a colour wheel. Saturation determines “how much” of that colour is displayed. And luminance determines “how bright/dark” that colour is.
So here’s the code to convert HSL to RGB (in the form of a System.Drawing.Color struct):
public System.Drawing.Color RgbFromHsl(double Hue, double Saturation, double Luminance)
{
double fChroma = (1.0 - Math.Abs(2.0 * Luminance - 1.0)) * Saturation;
double fHue = Hue / 60.0;
double fHueMod2 = fHue;
while (fHueMod2 >= 2.0) fHueMod2 -= 2.0;
double fTemp = fChroma * (1.0 - Math.Abs(fHueMod2 - 1.0));
double fRed = 0, fGreen = 0, fBlue = 0;
if (fHue < 1.0)
{
fRed = fChroma;
fGreen = fTemp;
fBlue = 0;
}
else if (fHue < 2.0)
{
fRed = fTemp;
fGreen = fChroma;
fBlue = 0;
}
else if (fHue < 3.0)
{
fRed = 0;
fGreen = fChroma;
fBlue = fTemp;
}
else if (fHue < 4.0)
{
fRed = 0;
fGreen = fTemp;
fBlue = fChroma;
}
else if (fHue < 5.0)
{
fRed = fTemp;
fGreen = 0;
fBlue = fChroma;
}
else if (fHue < 6.0)
{
fRed = fChroma;
fGreen = 0;
fBlue = fTemp;
}
else
{
fRed = 0;
fGreen = 0;
fBlue = 0;
}
double fMin = Luminance - 0.5 * fChroma;
fRed += fMin;
fGreen += fMin;
fBlue += fMin;
fRed *= 255.0;
fGreen *= 255.0;
fBlue *= 255.0;
int iRed = 0, iGreen = 0, iBlue = 0;
// the default seems to be to truncate rather than round
iRed = Convert.ToInt32(Math.Truncate(fRed));
iGreen = Convert.ToInt32(Math.Truncate(fGreen));
iBlue = Convert.ToInt32(Math.Truncate(fBlue));
if (iRed < 0) iRed = 0;
if (iRed > 255) iRed = 255;
if (iGreen < 0) iGreen = 0;
if (iGreen > 255) iGreen = 255;
if (iBlue < 0) iBlue = 0;
if (iBlue > 255) iBlue = 255;
return System.Drawing.Color.FromArgb(iRed, iGreen, iBlue);
}
The algorithm is taken from the Wikipedia page on HSL and HSV. I added some checks at the end to make sure the RGB values are within 0 to 255.
About the only problem I had was the mod function. It’s not “integer modulus”, it’s “floating point modulus” (is that a thing?). So 5.5 mod 2 is 1.5 (because the remainder of 5.5/2 is 1.5). That took me a couple of hours to figure out. This is one of the few cases where thinking in programming terms instead of the mathematical terms cost me.














I write about maths, programming, entrepreneurship and business stuff. I also make videos.





