Hue, Saturation and Lightness of sRGB Colors

This page defines the sHSL color space, which is based on sRGB and can be used to answer questions such as these:

1. How big is the contrast between light green (#66FF00) and violet (#6600FF)? (Just sufficient, but not perfect)

2. How do we reduce the saturation of blue (#0000FF) while keeping the same hue and brightness? (The wanted color is #3838C0)

3. Which shade of yellow has the same brightness and saturation as blue (#0000FF)? (Dark yellow #505000)

Introduction

In RGB representation, colors are described with three numbers for the red, green and blue components. Different devices often show slightly different colors for the same values. To solve this problem, the sRGB (standard RGB) color space has been defined. sRGB is widely supported by digital devices such as scanners, webcams, HDTV screens, projectors, cameras, photo CDs and reprint machines. It is also used in many standards (e.g. HTML, SVG, ODF).

Changes in one of the three components influence the hue, the saturation and the brightness of the color. Hence, it is almost impossible to compare and change colors in RGB representation. To compute alterations a color, we need to first calculate the hue, saturation and lightness of the color and then to convert the changed values back to sRGB.

The most commonly used alternative to RGB is called HSV or HSB (hue, saturation and brightness/value). HSV/HSB is unsuitable for our purpose, because the brightness component does not represent the real brightness of the color. The real brightness is also influenced by the hue and saturation:

HSV color space

A third popular color space is called HSL (hue, saturation and lightness/luminosity). It has the advantage that the saturation component is separated from the brightness, but the simple RGB to HSL conversion algorithm used by most applications still has problems. For example, the hue component still influences the brightness of the color:

HSL color space

It is possible to define a correct conversion from sRGB to HSL. To distinguish the color space defined like this from all other possible HSL color spaces, we name it sHSL in allusion to sRGB.

The conversion from sRGB to sHSL is more difficult but it leads to much better results:

HSV color space with hue-adjusted lightness

Luminosity (Lightness) and Contrast

The sRGB color space defines the red (R), green (G) and blue (B) components as numbers between 0 and 255. It also has a gamma value of 2.2, which means that the components can be normalized into a range from 0 to 1 (inclusive) like this:

Nr=(R/255)^2.2, Ng=(G/255)^2.2, Nb=(B/255)^2.2

The luminosity (L) of a color can then be calculated as a number between 0 (for black) and 1 (for white):

L = fr·Nr + fg·Ng + fb·Nb

using the factors

fr=0.2126, fg=0.7152, fb=0.0722

This formula is taken from the document "Understanding WCAG 2.0" that is released by W3C together with the Web Content Accessibility Guidelines (WCAG 2.0). It uses factors from the sRGB standard which in turn are based on an ITU standard for HDTV. Most modern computer screens use similar factors.

"Understanding WCAG 2.0" also describes how to evaluate the contrast between two colors (X and Y). The luminosity contrast ratio (Δ) has a range of 1 to 21. It needs to be bigger than 5 for sufficient contrast and bigger than 10 for good contrast.

Δ = (LX + 0.05) / (LY + 0.05)

Hue

We now assign r, g and b one of the numbers 0, 1 and -1 each so that

N1 = max { Nr, Ng, Nb }
N-1 = min { Nr, Ng, Nb }
r+g+b=0

The common definition for the hue (H) as a number between 0 (inclusive) and 360 (exclusive) can then be written as:

For N1 = N-1:   H = 0
For Nb = N-1 < N1:   H = (Ng-Nr)/(N1-N-1)·60
For Nr = N-1 < N1:   H = (Nb-Ng)/(N1-N-1)·60 + 120
For Ng = N-1 < N1:   H = (Nr-Nb)/(N1-N-1)·60 + 240

Saturation

The saturation (S) is a number between 0 (for gray, white and black) and 1 (for full saturation).

For L = 0:   S = 0
For L = 1:   S = 0
For 0<L<1:   S = max { (L-N-1)/L , (N1-L)/(1-L) }

The mathematical derivation from the definitions of hue and luminosity to this simple formula is quite long and is therefore not shown on this page.

Conversion from sHSL to sRGB

The first step is to calculate some hue-dependent variables.

r = |H - H mod 60 - 150| / 60 - 1.5
g = |H - H mod 60 + 110| / 60 - 1.5
b = |H - H mod 60 - 30| / 60 - 1.5
h = 1 - |(H mod 120)/60 - 1|
m = f1 + h·f0   (using fr,fg,fb from above)

We now differenciate between two cases.

For 0 ≤ L ≤ m:
N1 = L + L·S·(1-m)/m
N0 = L + L·S·(h-m)/m
N-1 = L - L·S

For m < L ≤ 1:
N1 = L + (1-L)·S
N0 = L + (1-L)·S·(h-m)/(1-m)
N-1 = L - (1-L)·S·m/(1-m)

The last step is to de-normalize the values for red, green and blue:

R=255·Nr^(1/2.2), G=255·Ng^(1/2.2), B=255·Nb^(1/2.2)

Changing the Luminosity of a Color

If you only wish to change the luminosity of a color (L#), then this formula can be used:

L = fr·Nr + fg·Ng + fb·Nb
m = f1 + f0 · (N0-N-1) / (N1-N-1)
D = min { L / m , (1-L) / (1-m) }
D# = min { L# / m , (1-L#) / (1-m) }

N#r = L# + (Nr-L)·D#/D
N#g = L# + (Ng-L)·D#/D
N#b = L# + (Nb-L)·D#/D

The conversion of R, G and B to Nr, b, g, 1, 0, -1 and fr, b, g, 1, 0, and back from N#r, g, b to R#, B# and G# is done as described above.

Changing the Saturation of a Color

If you only wish to change the saturation of a color (S#), then this formula can be used:

L = fr·Nr + fg·Ng + fb·Nb
h = (N0-N-1) / (N1-N-1)
m = f1 + f0 · h
D = min { L / m , (1-L) / (1-m) }

N#1 = L + S#·D·(1-m)
N#0 = L + S#·D·(h-m)
N#-1 = L + S#·D·m

The conversion of R, G and B to Nr, b, g, 1, 0, -1 and fr, b, g, 1, 0, and back from N#1, 0, -1 to R#, B# and G# is done as described above.

Changing the Hue of a Color

If you only wish to change the hue of a color (H#), then this formula can be used:

L = fr·Nr + fg·Ng + fb·Nb
m = f1 + f0 · (N0-N-1) / (N1-N-1)
D = min { L / m , (1-L) / (1-m) }

h# = 1 - |(H# mod 120)/60 - 1|
m# = f#1 + f#0 · h#
D# = min { L / m# , (1-L) / (1-m#) }

N#1 = L + (1-m#)·(N1-N-1)·D#/D
N#0 = L + (h#-m#)·(N1-N-1)·D#/D
N#-1 = L + m#·(N1-N-1)·D#/D

The conversion of R, G, B and H# to Nr, b, g, 1, 0, -1, fr, b, g, 1, 0 and f#1, 0, and back from N#1, 0, -1 to R#, B# and G# is done as described above.

(Olaf Schmidt, Gunnar Schmidt)

Inform

Skip menu "Inform"

Communicate

Skip menu "Communicate"

Develop

Skip menu "Develop"

Explore

Skip menu "Explore"