## 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*:

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:

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:

## 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:

```
N
```

_{r}=(R/255)^{^2.2},
N_{g}=(G/255)^{^2.2},
N_{b}=(B/255)^{^2.2}

```
L = f
```

_{r}·N_{r} + f_{g}·N_{g} + f_{b}·N_{b}

using the factors

```
f
```

_{r}=0.2126,
f_{g}=0.7152,
f_{b}=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.

```
Δ = (L
```

_{X} + 0.05) / (L_{Y} + 0.05)

## Hue

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

```
N
```

_{1} = max { N_{r}, N_{g}, N_{b} }

N_{-1} = min { N_{r}, N_{g}, N_{b} }

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 N
```_{1} = N_{-1}: H = 0

For N_{b} = N_{-1} < N_{1}:
H = (N_{g}-N_{r})/(N_{1}-N_{-1})·60

For N_{r} = N_{-1} < N_{1}:
H = (N_{b}-N_{g})/(N_{1}-N_{-1})·60 + 120

For N_{g} = N_{-1} < N_{1}:
H = (N_{r}-N_{b})/(N_{1}-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 , (N_{1}-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 = f_{1} + h·f_{0} (using f_{r},f_{g},f_{b} from above)

We now differenciate between two cases.

```
For 0 ≤ L ≤ m:
```

N_{1} = L + L·S·(1-m)/m

N_{0} = L + L·S·(h-m)/m

N_{-1} = L - L·S

```
For m < L ≤ 1:
```

N_{1} = L + (1-L)·S

N_{0} = 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·N
```_{r}^{^(1/2.2)},
G=255·N_{g}^{^(1/2.2)},
B=255·N_{b}^{^(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 = f
```_{r}·N_{r} + f_{g}·N_{g} + f_{b}·N_{b}

m = f_{1} + f_{0} · (N_{0}-N_{-1}) / (N_{1}-N_{-1})

D = min { L / m , (1-L) / (1-m) }

D^{#} = min { L^{#} / m , (1-L^{#}) / (1-m) }

```
N
```^{#}_{r} = L^{#} + (N_{r}-L)·D^{#}/D

N^{#}_{g} = L^{#} + (N_{g}-L)·D^{#}/D

N^{#}_{b} = L^{#} + (N_{b}-L)·D^{#}/D

The conversion of R, G and B to N_{r, b, g, 1, 0, -1} and
f_{r, 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 = f
```_{r}·N_{r} + f_{g}·N_{g} + f_{b}·N_{b}

h = (N_{0}-N_{-1}) / (N_{1}-N_{-1})

m = f_{1} + f_{0} · 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 N_{r, b, g, 1, 0, -1} and
f_{r, 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 = f
```_{r}·N_{r} + f_{g}·N_{g} + f_{b}·N_{b}

m = f_{1} + f_{0} · (N_{0}-N_{-1}) / (N_{1}-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^{#})·(N_{1}-N_{-1})·D^{#}/D

N^{#}_{0} = L + (h^{#}-m^{#})·(N_{1}-N_{-1})·D^{#}/D

N^{#}_{-1} = L + m^{#}·(N_{1}-N_{-1})·D^{#}/D

The conversion of R, G, B and H^{#} to N_{r, b, g, 1, 0, -1},
f_{r, 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)

```
```