BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Graphics
.NET 1.1+

Converting Between RGB and HSL Colour Models

The RGB colour model is ideal for producing images on display devices but counter-intuitive for people who wish to adjust colours. The HSL model is intuitive but not fully supported by .NET. This article explains how to convert between the two models.

Converting from HSL to System.Color

The process used to convert a HSL colour to RGB, and finally to a Color structure, is the reverse of the RGB to HSL conversion. To begin, create a class named, "HSLToColorConverter". Add the Convert method signature to the method and the code to initialise the target RGB value as follows:

public class HSLToColorConverter
{
    public Color Convert(HSL hsl)
    {
        RGB rgb = new RGB();
    }
}

As with the previous conversion there is a special case when the colour represented is grey, indicated by a saturation of zero. In this situation the red, green and blue elements of the target RGB colour will be set to match the lightness of the HSL colour. The hue will have no effect. We can implement the special case with the following code in the Convert method. Note that when the saturation is not zero, the as yet undefined GetRGBFromHSLWithChroma method is called.

if (hsl.S == 0M)
    rgb.R = rgb.G = rgb.B = hsl.L;
else
    rgb = GetRGBFromHSLWithChroma(hsl);

return rgb.ToColor();

To implement the missing method we need to first divide the hue value to change the upper limit of the scale from 360 to one. We will then calculate the maximum and minimum values for the RGB values and use these three pieces of information to obtain each component using another method that we have not yet defined. Add the following method to the code:

private RGB GetRGBFromHSLWithChroma(HSL hsl)
{
    decimal min, max, h;

    h = hsl.H / 360M;

    max = hsl.L < 0.5M ? hsl.L * (1 + hsl.S): (hsl.L + hsl.S) - (hsl.L * hsl.S);
    min = (hsl.L * 2M) - max;

    RGB rgb = new RGB();
    rgb.R = ComponentFromHue(min, max, h + (1M / 3M));
    rgb.G = ComponentFromHue(min, max, h);
    rgb.B = ComponentFromHue(min, max, h - (1M / 3M));
    return rgb;
}

The final private method converts the maximum, minimum and adjusted hue values to a single red, green or blue value. This converts back from the HSL cylinder model to the RGB cube co-ordinates.

private decimal ComponentFromHue(decimal m1, decimal m2, decimal h)
{
    h = (h + 1M) % 1M;
    if ((h * 6M) < 1)
        return m1 + (m2 - m1) * 6M * h;
    else if ((h * 2M) < 1)
        return m2;
    else if ((h * 3M) < 2)
        return m1 + (m2 - m1) * ((2M / 3M) - h) * 6M;
    else
        return m1;
}

Using the Conversions

We can now test the two conversions. The following code starts with the named, "OrangeRed" colour in a Color structure. This is converted to the HSL notation so that the lightness can be increased. Finally, the HSL values are converted back to a new, lighter RGB Color value.

ColorToHSLConverter rgbToHsl = new ColorToHSLConverter();
HSLToColorConverter hslToRgb = new HSLToColorConverter();

Color original = Color.OrangeRed;
HSL hsl = rgbToHsl.Convert(original);
hsl.L = hsl.L + 0.2M;
Color lighter = hslToRgb.Convert(hsl);

If you display the OrangeRed and the lightened version you will see the colours show below:

To try more conversions, download the demo and source code using the link at the top of the article. This includes the code for a simple Windows forms application that allows you to modify the RGB and HSL values for a colour and see the effects in both colour models. It also includes the entire code for the two conversions for use in your own projects.

17 November 2010