Academic Tutorials

English | French | Portugese | German | Italian
Home Advertise Payments Recommended Websites Interview Questions FAQs
News Source Codes E-Books Downloads Jobs Web Hosting

Graphics Introduction
Graphics Printmaking
Graphics Photography
Graphics for Web
Computer graphics
Computer graphics II
Graphics C++, SDL
Graphics QuickCG
Graphics Light and Color
Graphics Color Model
Graphics Image
Graphics 2D Drawing
Graphics Flood Fill
Graphics Clipping
Graphics Fractals
Graphics Sierpinski
Graphics Julia
Graphics Fire Effect
Graphics Tunnel Effect
graphics Raycasting
Graphics Raycaster
Graphics Floor & Ceiling
Graphics Sprites
Graphics Filtering
Graphics Fourier Trans
Graphics FT on Images
Graphics DC Component
Graphics Texture Gen..
Graphics Random Noise
Graphics Clouds

HTML Tutorials
HTML Tutorial
XHTML Tutorial
CSS Tutorial
TCP/IP Tutorial
CSS 1.0
CSS 2.0
XML Tutorials
XML Tutorial
XSL Tutorial
XSLT Tutorial
DTD Tutorial
Schema Tutorial
XForms Tutorial
XSL-FO Tutorial
XML DOM Tutorial
XLink Tutorial
XQuery Tutorial
XPath Tutorial
XPointer Tutorial
RDF Tutorial
SOAP Tutorial
WSDL Tutorial
RSS Tutorial
WAP Tutorial
Web Services Tutorial
Browser Scripting
JavaScript Tutorial
VBScript Tutorial
DHTML Tutorial
HTML DOM Tutorial
WMLScript Tutorial
E4X Tutorial
Server Scripting
ASP Tutorial
PERL Tutorial
SQL Tutorial
ADO Tutorial
Apple Script
PL/SQL Tutorial
SQL Server
.NET (dotnet)
.Net Mobile
C# : C Sharp
SVG Tutorial
Flash Tutorial
Media Tutorial
SMIL Tutorial
Photoshop Tutorial
Gimp Tutorial
Gnuplot Programming
GIF Animation Tutorial
Scientific Visualization Tutorial
Web Building
Web Browsers
Web Hosting
W3C Tutorial
Web Building
Web Quality
Web Semantic
Web Careers
Weblogic Tutorial
Web Site Hosting
Domain Name
Java Tutorials
Java Tutorial
JSP Tutorial
Servlets Tutorial
Struts Tutorial
EJB Tutorial
JMS Tutorial
JMX Tutorial
Programming Langauges
C Tutorial
C++ Tutorial
Visual Basic Tutorial
Data Structures Using C
Assembly Language
Forth Programming
Lisp Programming
Data Warehousing
CGI Programming
Emacs Tutorial
Soft Skills
Communication Skills
Time Management
Project Management
Team Work
Leadership Skills
Corporate Communication
Negotiation Skills
Database Tutorials
Operating System
Software Testing
SAP Module
Business Warehousing
SAP Basis
Material Management
Sales & Distribution
Human Resource
Customer Relationship Management
Production and Planning
Networking Programming
Corba Tutorial
Networking Tutorial
Microsoft Office
Microsoft Word
Microsoft Outlook
Microsoft PowerPoint
Microsoft Publisher
Microsoft Excel
Microsoft Front Page
Microsoft InfoPath
Microsoft Access
Financial Accounting
Managerial Accounting
Network Sites

The HSL Color Model

Previoushome Next

The HSL Color Model


HSL is another way to describe color with 3 parameters. RGB is the way computer screens work, but not very intuitive. HSL is more intuitive, but you need to convert it to RGB before you can draw a pixel with it. The nicest application of this color model is that you can easily create rainbow gradients or change the color, lightness or saturation of an image with this color model.

HSL color obviously has the parameters H, S and L, or Hue, Saturation and Lightness.

Hue indicates the color sensation of the light, in other words if the color is red, yellow, green, cyan, blue, magenta, ... This representation looks almost the same as the visible spectrum of light, except on the right is now the color magenta (the combination of red and blue), instead of violet (light with a frequency higher than blue):

Hue works circular, so it can be represented on a circle instead. A hue of 360 looks the same again as a hue of 0.

Saturation indicates the degree to which the hue differs from a neutral gray. The values run from 0%, which is no color, to 100%, which is the fullest saturation of a given hue at a given percentage of illumination. The more the spectrum of the light is concentrated around one wavelength, the more saturated the color will be.

Lightness indicates the illumination of the color, at 0% the color is completely black, at 50% the color is pure, and at 100% it becomes white. In HSL color, a color with maximum lightness (L=255) is always white, no matter what the hue or saturation components are. Lightness is defined as (maxColor+minColor)/2 where maxColoris the R, G or B component with the maximum value, and minColor the one with the minimum value.

In this tutorial, Hue, Saturation and Lightness will be presented as numbers between 0-255 instead, so that the HSL model has the same 24 bits as the RGB model.

The HSL color model is for example used in Paint Shop Pro's color picker.

The HSV Color Model

The HSV color model (sometimes also called HSB), uses the parameter Value instead of Lightness. Value works different than Lightness, in that the color with maximum value (V=255) can be any color like red, green, yellow, white, etc..., at it'smaximum brightness. Value is defined as maxColor, where maxColor is the R, G or B component with the maximum value. So the colors red (255,0,0) and white (255,255,255) both have a Value of 255 indeed.

In HSL, the Lightness showed the following behavior when increased:

In HSV, Value does the following:

The Hue and Saturation parameters work very similar to the ones in HSL. HSV is generally better at representing the saturation, while HSL is better at representing the brightness. However, HSV is again better to decrease the brightness of very bright images.

We can compare the HSL and HSV model a bit better by comparing their plots:

Here is the plot of HSL (left) and HSV (right) with S=255, Hue on the horizontal axis, and Lightness/Value on the vertical axis (maximum lightness at the top):

While the top of the HSL curve is white because white is the color with maximum brightness, the top of the HSV curve contains all colors, because the saturation is 255 and in HSV, saturation 255 has to be a color while white should have 0 saturation. The top of the HSV curve is the same as the center horizontal line of the HSL curve, and the complete HSV curve is exactly the same as the bottom half of the HSL picture.

Here is the plot of HSL (left) and HSV (right) with L=255 and V=255 respectively, Hue on the horizontal axis, and Saturation on the vertical axis (maximum saturation at the bottom):

The HSL curve is completely white, because white is the only color with L=255 in the HSL model. The HSV curve, now shows all colors that have one or more of their color components equal to 255. The HSV picture here, is exactly the same as the top half of the previous HSL picture where S=255.

And here's the plot of HSL (left) and HSV (right) with L=128 and V=128 respectively, and again Hue on the horizontal axis, and Saturation on the vertical axis (maximum saturation at the bottom):

Color Model Conversions

To draw the plots given above, color model conversion functions have to be used: first you describe the color as HSL or HSV, but to plot it on screen, it has to be converted to RGB first. Transformations from RGB to HSL/HSV are handy as well, for example if you load an RGB image and want to change it hue, you have to convert it to HSL or HSV first, then change the hue, and then change it back to RGB.

The color model conversion formulas are already in QuickCG, in the QuickCG.cpp file.


The following function converts from RGB color to HSL color. You give it a ColorRGB and it returns a ColorHSL. Both ColorRGB and ColorHSL are simple structs with 3 integers, the only difference is their names. The RGBtoHSL function calculates the values for ColorHSL.

First the variables r, g, b, h, s, l are declared as floating point numbers. Internally, the function works with floating point numbers between 0.0 and 1.0, for better precision. At the end of the function, the results can very easily be converted back to integers from 0-255. The function can also easily be modified to work with other ranges, e.g. if you'd want to use 16 bit per color channel, or represent Hue as a value between 0 and 360.

ColorHSL RGBtoHSL(ColorRGB colorRGB) 
    float r, g, b, h, s, l; //this function works with floats between 0 and 1 
    r = colorRGB.r / 256.0; 
    g = colorRGB.g / 256.0; 
    b = colorRGB.b / 256.0;

Then, minColor and maxColor are defined. Mincolor is the value of the color component with the smallest value, while maxColor is the value of the color component with the largest value. These two variables are needed because the Lightness is defined as (minColor + maxColor) / 2.

    float maxColor = max(r, max(g, b)); 
    float minColor = min(r, min(g, b));

If minColor equals maxColor, we know that R=G=B and thus the color is a shade of gray. This is a trivial case, hue can be set to anything, saturation has to be set to 0 because only then it's a shade of gray, and lightness is set to R=G=B, the shade of the gray.

    //R == G == B, so it's a shade of gray
        h = 0.0; //it doesn't matter what value it has       
        s = 0.0;       
        l = r; //doesn't matter if you pick r, g, or b   

If minColor is not equal to maxColor, we have a real color instead of a shade of gray, so more calculations are needed:
  • Lightness (l) is now set to it's definition of (minColor + maxColor)/2.
  • Saturation (s) is then calculated with a different formula depending if light is in the first half of the second half. This is because the HSL model can be represented as a double cone, the first cone has a black tip and corresponds to the first half of lightness values, the second cone has a white tip and contains the second half of lightness values.
  • Hue (h) is calculated with a different formula depending on which of the 3 color components is the dominating one, and then normalized to a number between 0 and 1.

        l = (minColor + maxColor) / 2;     
        if(l < 0.5) s = (maxColor - minColor) / (maxColor + minColor);
        else s = (maxColor - minColor) / (2.0 - maxColor - minColor);
        if(r == maxColor) h = (g - b) / (maxColor - minColor);
        else if(g == maxColor) h = 2.0 + (b - r) / (maxColor - minColor);
        else h = 4.0 + (r - g) / (maxColor - minColor);
        h /= 6; //to bring it to a number between 0 and 1
        if(h < 0) h ++;

Finally, H, S and L are calculated out of h,s and l as integers between 0 and 255 and "returned" as the result. Returned, because H, S and L were passed by reference to the function.

    ColorHSL colorHSL;
    colorHSL.h = int(h * 255.0);
    colorHSL.s = int(s * 255.0);
    colorHSL.l = int(l * 255.0);
    return colorHSL;


This is the opposite conversion, so this function will calculate the inverse of the RGBtoHSL function.

First, internally the variables with small letters are defined as floating point numbers between 0 and 1 again. Some temporary values for the calculations are also declared.

ColorRGB HSLtoRGB(ColorHSL colorHSL)
    float r, g, b, h, s, l; //this function works with floats between 0 and 1
    float temp1, temp2, tempr, tempg, tempb;
    h = colorHSL.h / 256.0;
    s = colorHSL.s / 256.0;
    l = colorHSL.l / 256.0;

Then follows a trivial case: if the saturation is 0, the color will be a grayscale color, and the calculation is then very simple: r, g and b are all set to the lightness.

    //If saturation is 0, the color is a shade of gray
    if(s == 0) r = g = b = l;

If the saturation is higher than 0, more calculations are needed again. red, green and blue are calculated with the formulas defined in the code.

    //If saturation > 0, more complex calculations are needed
        //Set the temporary values      
        if(l < 0.5) temp2 = l * (1 + s);      
        else temp2 = (l + s) - (l * s);     
        temp1 = 2 * l - temp2;    
        tempr = h + 1.0 / 3.0;    
        if(tempr > 1) tempr--;
        tempg = h;     
        tempb = h - 1.0 / 3.0;
        if(tempb < 0) tempb++; 
        if(tempr < 1.0 / 6.0) r = temp1 + (temp2 - temp1) * 6.0 * tempr;      
        else if(tempr < 0.5) r = temp2;   
        else if(tempr < 2.0 / 3.0) r = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempr) * 6.0;
        else r = temp1; 
        if(tempg < 1.0 / 6.0) g = temp1 + (temp2 - temp1) * 6.0 * tempg;    
        else if(tempg < 0.5) g = temp2;
        else if(tempg < 2.0 / 3.0) g = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempg) * 6.0;
        else g = temp1; 
        if(tempb < 1.0 / 6.0) b = temp1 + (temp2 - temp1) * 6.0 * tempb;   
        else if(tempb < 0.5) b = temp2; 
        else if(tempb < 2.0 / 3.0) b = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempb) * 6.0;    
        else b = temp1;

And finally, the results are returned as integers between 0 and 255.

    ColorRGB colorRGB;
    colorRGB.r = int(r * 255.0);
    colorRGB.g = int(g * 255.0);
    colorRGB.b = int(b * 255.0);
    return colorRGB;


The function RGBtoHSV works very similar as the RGBtoHSL function, the only difference is that now the variable V (Value) instead of L (Lightness) is used, and Value is defined as maxColor. This can immediately be calculated at the beginning of the function:

ColorHSV RGBtoHSV(ColorRGB colorRGB) 
    float r, g, b, h, s, v; //this function works with floats between 0 and 1 
    r = colorRGB.r / 256.0; 
    g = colorRGB.g / 256.0; 
    b = colorRGB.b / 256.0;
    float maxColor = max(r, max(g, b));
    float minColor = min(r, min(g, b));
    v = maxColor;

Then, the saturation is calculated. If the color is black, the value of saturation doesn't matter so it can be set to 0. This has to be done to avoid a division by zero.

    if(maxColor == 0)//avoid division by zero when the color is black
        s = 0;
        s = (maxColor - minColor) / maxColor;

Finally, the hue is calculated. If saturation is 0, the color is gray so hue doesn't matter. Again this case is handled separately to avoid divisions by zero.

    if(s == 0)
        h = 0; //it doesn't matter what value it has
        if(r == maxColor) h = (g - b) / (maxColor-minColor); 
        else if(g == maxColor) h = 2.0 + (b - r) / (maxColor - minColor);
        else h = 4.0 + (r - g) / (maxColor - minColor);       
        h /= 6.0; //to bring it to a number between 0 and 1
        if (h < 0) h++;

And finally, the results are returned as integers between 0 and 255.

    ColorHSV colorHSV;
    colorHSV.h = int(h * 255.0);
    colorHSV.s = int(s * 255.0);
    colorHSV.v = int(v * 255.0);
    return colorHSV;


First the floating point numbers between 0 and 1 are declared again:

ColorRGB HSVtoRGB(ColorHSV colorHSV) 
    float r, g, b, h, s, v; //this function works with floats between 0 and 1 
    h = colorHSV.h / 256.0; 
    s = colorHSV.s / 256.0; 
    v = colorHSV.v / 256.0;

The trivial case for saturation = zero is handled:

    //If saturation is 0, the color is a shade of gray
    if(s == 0) r = g = b = v;

The HSV model can be presented on a cone with hexagonal shape. For each of the sides of the hexagon, a separate case is calculated:

    //If saturation > 0, more complex calculations are needed
        float f, p, q, t;
        int i;
        h *= 6; //to bring hue to a number between 0 and 6, better for the calculations
        i = int(floor(h));  //e.g. 2.7 becomes 2 and 3.01 becomes 3 or 4.9999 becomes 4
        f = h - i;  //the fractional part of h
        p = v * (1 - s);   
        q = v * (1 - (s * f));     
        t = v * (1 - (s * (1 - f)));   
            case 0: r = v; g = t; b = p; break;
            case 1: r = q; g = v; b = p; break;
            case 2: r = p; g = v; b = t; break;
            case 3: r = p; g = q; b = v; break;
            case 4: r = t; g = p; b = v; break;
            case 5: r = v; g = p; b = q; break;  

And again, the results are "returned" as integers between 0 and 255.

    ColorRGB colorRGB;
    colorRGB.r = int(r * 255.0);
    colorRGB.g = int(g * 255.0);
    colorRGB.b = int(b * 255.0);
    return colorRGB;

HSL and HSV Arithmetic

The functions given above are already in the QuickCG, and thanks to them we can do HSL and HSV arithmetic on images.

The examples will be performed on the flower image again:

Changing Hue

It doesn't matter if you change hue with the HSL or HSV model, the results are the same, so for no particular reason at all let's do it with HSL here.

The following code will load the BMP image, convert it to HSL, change the Hue by adding a certain value to it, and convert it back to RGB to display it (put this code in the main function in the main.cpp file):

ColorRGB image[200][133]; 
int main(int argc, char *argv[])  
    ColorRGB colorRGB; 
    ColorHSL colorHSL; 
    screen(200, 133, 0, "HSL and HSV Color"); 
    loadBMP("pics/flower.bmp", image[0], 200, 133); 
    for(int x = 0; x < w; x++) 
    for(int y = 0; y < h; y++) 
        //store the color of the image in variables R, G and B 
        colorRGB = image[x][y]; 
        //calculate H, S and L out of R, G and B 
        colorHSL = RGBtoHSL(colorRGB); 
        //change Hue 
        colorHSL.h += int(42.5 * 1); 
        colorHSL.h %= 255; 
        //convert back to RGB 
        colorRGB = HSLtoRGB(colorHSL); 
        //plot the pixel 
        pset(x, y, colorRGB); 
    return 0; 

The Hue is modulo divided through 255, because it has to be between 0 and 255, and it's circular, so a hue of 260 is the same as a hue of 5. The value 42.5 was chosen to be 255/6, representing a hue shift of 60. Here are screenshots of the result for a hue shift of 0, 60, 120, 180, 240 and 300 (360 gives the same result as 0 again):

You can also set Hue to a constant, to give the whole image the same color. For example, here hue is set to 25, which is orange:

Changing Saturation

You can change the saturation to make the image more colorful, or more like pastel, or grayscale. This time, the results are slightly different if you use the HSL or HSV color model.

For example, to increase the saturation by multiplying it with 2.5, change the lines of the code that changed the hue to:

    colorHSV.s = int(colorHSV.s * 2.5);  
    if(colorHSV.s > 255) colorHSV.s = 255;

If Saturation is higher than 255, it's truncated. On the left is the result if you use HSL, on the right if you use HSV. The result is pretty similar to the original image because the saturation in it was quite high already. Only the background became a bit more green.

If you multiply it with 0.5 instead, you'll decrease the saturation by halving it:

You can also decrease the saturation by substracting a value from it instead:

    colorHSV.s = colorHSV.s - 100;
    if(colorHSV.s < 0) colorHSV.s = 0;

The background will be grayscale now, while the flower with it's high saturation still has some color:

If saturation is set to 0, the image will be grayscale, in a different way if you use HSL or HSV, and both are also different from the "average" formula to grayscale an image:

And this is what you get if you set saturation equal to 128 for all pixels. The flower and background look equally colorful now:

Changing Brightness

Finally, HSL and HSV can also be used to change the brightness of an image. Again, the HSL and HSV model will work differently. HSL gives bad result when making an image with white or near white pixels darker.

You can also decrease the saturation by substracting a value from it instead:

    colorHSV.l -= 50;
    if(colorHSV.l < 0) colorHSV.l = 0;

Here's the result for HSL on the left and HSV on the right:

And setting brightness equal to 192 for all pixels gives:

© Lode Vandevenne. Reproduced with permission.

Be the first one to comment on this page.

  Graphics eBooks
More Links » »
 Graphics FAQs
More Links » »
 Graphics Interview Questions
More Links » »
 Graphics Articles
More Links » »
 Graphics News
More Links » »
 Graphics Jobs
More Links » »

Share And Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • blinkbits
  • BlinkList
  • blogmarks
  • co.mments
  • connotea
  • digg
  • Fark
  • feedmelinks
  • Furl
  • LinkaGoGo
  • Ma.gnolia
  • NewsVine
  • Netvouz
  • RawSugar
  • Reddit
  • scuttle
  • Shadows
  • Simpy
  • Smarking
  • Spurl
  • TailRank
  • Wists
  • YahooMyWeb

Previoushome Next

Keywords: The HSL Color Model, Graphics, Graphics, Graphics tutorial, Graphics tutorial pdf, history of Graphics, learn Graphics

HTML Quizzes
CSS Quiz
CSS 1.0 Quiz
CSS 2.0 Quiz
XML Quizzes
XML Quiz
XSL Quiz
DTD Quiz
Schema Quiz
XForms Quiz
XLink Quiz
XQuery Quiz
XPath Quiz
XPointer Quiz
RDF Quiz
RSS Quiz
WAP Quiz
Web Services Quiz
Browser Scripting Quizzes
JavaScript Quiz
VBScript Quiz
WMLScript Quiz
E4X Quiz
Server Scripting Quizzes
ASP Quiz
SQL Quiz
ADO Quiz
CVS Quiz
Python Quiz
Apple Script Quiz
SQL Server Quiz
PHP Quiz
.NET (dotnet) Quizzes
Microsoft.Net Quiz
ASP.Net Quiz
.Net Mobile Quiz
C# : C Sharp Quiz
VC++ Quiz
Multimedia Quizzes
SVG Quiz
Flash Quiz
Media Quiz
Photoshop Quiz
Gimp Quiz
Matlab Quiz
Gnuplot Programming Quiz
GIF Animation Quiz
Scientific Visualization Quiz
Graphics Quiz
Web Building Quizzes
Web Browsers Quiz
Web Hosting Quiz
W3C Quiz
Web Building Quiz
Web Quality Quiz
Web Semantic Quiz
Web Careers Quiz
Weblogic Quiz
SEO Quiz
Web Site Hosting Quiz
Domain Name Quiz
Java Quizzes
Java Quiz
JSP Quiz
Servlets Quiz
Struts Quiz
EJB Quiz
JMS Quiz
JMX Quiz
Eclipse Quiz
J2ME Quiz
Programming Langauges Quizzes
C Quiz
C++ Quiz
Visual Basic Quiz
Data Structures Using C Quiz
Cobol Quiz
Assembly Language Quiz
Mainframe Quiz
Forth Programming Quiz
Lisp Programming Quiz
Pascal Quiz
Delphi Quiz
Fortran Quiz
OOPs Quiz
Data Warehousing Quiz
CGI Programming Quiz
Emacs Quiz
Gnome Quiz
ILU Quiz
Soft Skills Quizzes
Communication Skills Quiz
Time Management Quiz
Project Management Quiz
Team Work Quiz
Leadership Skills Quiz
Corporate Communication Quiz
Negotiation Skills Quiz
Database Quizzes
Oracle Quiz
MySQL Quiz
Operating System Quizzes
BSD Quiz
Symbian Quiz
Unix Quiz
Internet Quiz
IP-Masquerading Quiz
IPC Quiz
Software Testing Quizzes
Testing Quiz
Firewalls Quiz
SAP Module Quizzes
ERP Quiz
Business Warehousing Quiz
SAP Basis Quiz
Material Management Quiz
Sales & Distribution Quiz
Human Resource Quiz
Netweaver Quiz
Customer Relationship Management Quiz
Production and Planning Quiz
Networking Programming Quizzes
Corba Quiz
Networking Quiz
Microsoft Office Quizzes
Microsoft Word Quiz
Microsoft Outlook Quiz
Microsoft PowerPoint Quiz
Microsoft Publisher Quiz
Microsoft Excel Quiz
Microsoft Front Page Quiz
Microsoft InfoPath Quiz
Microsoft Access Quiz
Accounting Quizzes
Financial Accounting Quiz
Managerial Accounting Quiz
Testimonials | Contact Us | Link to Us | Site Map
Copyright 2008. Academic All rights reserved Privacy Policies | About Us
Our Portals : Academic Tutorials | Best eBooksworld | Beyond Stats | City Details | Interview Questions | Discussions World | Excellent Mobiles | Free Bangalore | Give Me The Code | Gog Logo | Indian Free Ads | Jobs Assist | New Interview Questions | One Stop FAQs | One Stop GATE | One Stop GRE | One Stop IAS | One Stop MBA | One Stop SAP | One Stop Testing | Webhosting in India | Dedicated Server in India | Sirf Dosti | Source Codes World | Tasty Food | Tech Archive | Testing Interview Questions | Tests World | The Galz | Top Masala | Vyom | Vyom eBooks | Vyom International | Vyom Links | Vyoms | Vyom World
Copyright 2003-2017 Vyom Technosoft Pvt. Ltd., All Rights Reserved.