Skip to content

Commit 1b5d639

Browse files
bors[bot]fu5ha
andauthored
Merge #147
147: Improve documentation about color (spaces) in README r=Ogeon a=termhn I am meaning to copy this over to the crate documentation but haven't done so yet. Also, I haven't really proof-read it at all, but am open to comments/suggestions as far as content goes :) Co-authored-by: Gray Olson <[email protected]>
2 parents 817daed + b92d422 commit 1b5d639

File tree

2 files changed

+79
-15
lines changed

2 files changed

+79
-15
lines changed

README.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,38 @@ features = ["libm"] # Makes it use libm instead of std for float math
4747

4848
## It's Never "Just RGB"
4949

50-
Colors in, for example, images are often "gamma corrected" or stored in sRGB format as a compression method and to prevent banding. This is also a bit of a legacy from the ages of the CRT monitors, where the output from the electron gun was nonlinear. The problem is that these formats don't represent the actual intensities, and the compression has to be reverted to make sure that any operations on the colors are accurate. This library uses a completely linear work flow, and comes with the tools for transitioning between linear and non-linear RGB.
50+
Colors in, for example, images, are often "gamma corrected", or converted using some non-linear transfer function into a format like sRGB before being stored or displayed. This is done as a compression method and to prevent banding, and is also a bit of a legacy from the ages of the CRT monitors, where the output from the electron gun was nonlinear. The problem is that these formats are *non-linear color spaces*, which means that many operations that you may want to perform on colors (addition, subtraction, multiplication, linear interpolation, etc.) will work unexpectedly when performed in such a non-linear color space. As such, the compression has to be reverted to restore linearity and make sure that many operations on the colors are accurate.
5151

52-
Adding to that, there are more than one kind of non-linear RGB. Ironically enough, this turns RGB into one of the most complex color spaces.
52+
But, even when colors *are* 'linear', there is yet more to explore.
53+
54+
The most common way that colors are defined, especially for computer storage, is in terms of so-called *tristimulus values*, meaning that all colors are defined as a vector of three values which may represent any color. The reason colors can generally be stored as only a three dimensional vector, and not an *n* dimensional one, where *n* is some number of possible frequencies of light, is because our eyes contain only three types of cones. Each of these cones have different sensitivity curves to different wavelengths of light, giving us three "dimensions" of sensitivity to color. These cones are often called the S, M, and L (for small, medium, and large) cones, and their sensitivity curves *roughly* position them as most sensitive to "red", "green", and "blue" parts of the spectrum. As such, we can choose only three values to represent any possible color that a human is able to see. An interesting consequence of this is that humans can see two different objects which are emitting *completely different actual light spectra* as the *exact same perceptual color* so long as those wavelengths, when transformed by the sensitivity curves of our cones, end up resulting in the same S, M, and L values sent to our brains.
55+
56+
A **color space** (which simply refers to a set of standards by which we map a set of arbitrary values to real-world colors) which uses tristimulus values is often defined in terms of
57+
58+
1. Its **primaries**
59+
2. Its **reference white** or **white point**
60+
61+
The **primaries** together represent the total *gamut* (i.e. displayable range of colors) of that color space, while the **white point** defines which concrete tristimulus value corresponds to a real, physical white reflecting object being lit by a known light source and observed by the 'standard observer' (i.e. a standardized model of human color perception).
62+
63+
The informal "RGB" color space is such a tristimulus color space, since it is defined by three values, but it is underspecified since we don't know which primaries are being used (i.e. how exactly are the canonical "red", "green", and "blue" defined?), nor its white point. In most cases, when people talk about "RGB" or "Linear RGB" colors, what they are *actually* talking about is the "Linear sRGB" color space, which uses the primaries and white point defined in the sRGB standard, but which *does not* have the (non-linear) sRGB *transfer function* applied.
64+
65+
This library takes these things into account, and attempts to provide an interface which will let those who don't care so much about the intricacies of color still use colors correctly, while also allowing the advanced user a high degree of flexibility in how they use it.
5366

5467
## What It Can Do
5568

5669
Palette provides tools for both color manipulation and conversion between color spaces. These are some highlights.
5770

5871
### Color Spaces
5972

60-
RGB is probably the most widely known color space, but it's not the only one. You have probably used a color picker with a rainbow wheel and a brightness slider. That may have been an HSV or an HSL color picker, where the color is encoded as hue, saturation and brightness/lightness. There's also a group of color spaces that are designed to be perceptually uniform, meaning that the perceptual change is equal to the numerical change.
73+
"RGB" (which we now know, from the discussion in the previous section, is usually actually Linear sRGB) and other tristimulus based spaces like CIE Xyz are probably the most widely known color spaces. These spaces are great when you want to perform physically correct math on color (like in a 2d or 3d rendering program) but there are also color spaces that are not defined in terms of tristimulus values.
74+
75+
You have probably used a color picker with a rainbow wheel and a brightness slider. That may have been an HSV or an HSL color picker, where the color is encoded as hue, saturation and brightness/lightness. Even though these spaces are defined using 3 values, they *aren't* based on tristimulus values, since those three values don't have a direct relation to human vision (i.e. our S, M, and L cones, as discussed in the previous section). Such color spaces are excellent when it comes to humans intuitively selecting color values, though, and as such are the go-to choice when this interaction is needed. They can then be converted into other color spaces in order to actually perform modifications to them
76+
77+
There's also a group of color spaces that are designed to be perceptually uniform, meaning that the perceptual change is equal to the numerical change. An example of this is the CIE L\*a\*b\* color space. These color spaces are excellent when you want to "blend" between colors in a *perceptually pleasing* manner (for example, in a data visualization) rather than a *physically correct* one.
6178

6279
Selecting the proper color space can have a big impact on how the resulting image looks (as illustrated by some of the programs in `examples`), and Palette makes the conversion between them as easy as a call to `from_color` or `into_color`.
6380

64-
This example takes an sRGB color, converts it to CIE L\*C\*h°, shifts its hue by 180° and converts it back to RGB:
81+
This example takes an sRGB color, converts it to CIE L\*C\*h°, a color space similar to the colloquial HSL/HSV color spaces, shifts its hue by 180° and converts it back to RGB:
6582

6683
```Rust
6784
use palette::{FromColor, Hue, IntoColor, Lch, Srgb};

palette/src/lib.rs

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44
//!
55
//! # It's Never "Just RGB"
66
//!
7-
//! Colors in, for example, images are often "gamma corrected" or stored in
8-
//! sRGB format as a compression method and to prevent banding. This is also a
9-
//! bit of a legacy from the ages of the CRT monitors, where the output from
10-
//! the electron gun was nonlinear. The problem is that these formats doesn't
11-
//! represent the actual intensities, and the compression has to be reverted to
12-
//! make sure that any operations on the colors are accurate. This library uses
13-
//! a completely linear work flow, and comes with the tools for transitioning
14-
//! between linear and non-linear RGB.
15-
//!
16-
//! Adding to that, there are more than one kind of non-linear RGB. Ironically
17-
//! enough, this turns RGB into one of the most complex color spaces.
7+
//! Colors in, for example, images, are often "gamma corrected", or converted
8+
//! using some non-linear transfer function into a format like sRGB before being
9+
//! stored or displayed. This is done as a compression method and to prevent banding,
10+
//! and is also a bit of a legacy from the ages of the CRT monitors, where the
11+
//! output from the electron gun was nonlinear. The problem is that these formats
12+
//! are *non-linear color spaces*, which means that many operations that you may want
13+
//! to perform on colors (addition, subtraction, multiplication, linear interpolation,
14+
//! etc.) will work unexpectedly when performed in such a non-linear color space. As
15+
//! such, the compression has to be reverted to restore linearity and make sure that
16+
//! many operations on the colors are accurate.
1817
//!
1918
//! For example, this does not work:
2019
//!
@@ -43,6 +42,54 @@
4342
//! .into_raw();
4443
//! ```
4544
//!
45+
//! But, even when colors *are* 'linear', there is yet more to explore.
46+
//!
47+
//! The most common way that colors are defined, especially for computer
48+
//! storage, is in terms of so-called *tristimulus values*, meaning that
49+
//! all colors are defined as a vector of three values which may represent
50+
//! any color. The reason colors can generally be stored as only a three
51+
//! dimensional vector, and not an *n* dimensional one, where *n* is some
52+
//! number of possible frequencies of light, is because our eyes contain
53+
//! only three types of cones. Each of these cones have different sensitivity
54+
//! curves to different wavelengths of light, giving us three "dimensions"
55+
//! of sensitivity to color. These cones are often called the S, M, and L
56+
//! (for small, medium, and large) cones, and their sensitivity curves
57+
//! *roughly* position them as most sensitive to "red", "green", and "blue"
58+
//! parts of the spectrum. As such, we can choose only three values to
59+
//! represent any possible color that a human is able to see. An interesting
60+
//! consequence of this is that humans can see two different objects which
61+
//! are emitting *completely different actual light spectra* as the *exact
62+
//! same perceptual color* so long as those wavelengths, when transformed
63+
//! by the sensitivity curves of our cones, end up resulting in the same
64+
//! S, M, and L values sent to our brains.
65+
//!
66+
//! A **color space** (which simply refers to a set of standards by which
67+
//! we map a set of arbitrary values to real-world colors) which uses
68+
//! tristimulus values is often defined in terms of
69+
//!
70+
//! 1. Its **primaries**
71+
//! 2. Its **reference white** or **white point**
72+
//!
73+
//! The **primaries** together represent the total *gamut* (i.e. displayable
74+
//! range of colors) of that color space, while the **white point** defines
75+
//! which concrete tristimulus value corresponds to a real, physical white
76+
//! reflecting object being lit by a known light source and observed by the
77+
//! 'standard observer' (i.e. a standardized model of human color perception).
78+
//!
79+
//! The informal "RGB" color space is such a tristimulus color space, since
80+
//! it is defined by three values, but it is underspecified since we don't
81+
//! know which primaries are being used (i.e. how exactly are the canonical
82+
//! "red", "green", and "blue" defined?), nor its white point. In most cases,
83+
//! when people talk about "RGB" or "Linear RGB" colors, what they are
84+
//! *actually* talking about is the "Linear sRGB" color space, which uses the
85+
//! primaries and white point defined in the sRGB standard, but which *does
86+
//! not* have the (non-linear) sRGB *transfer function* applied.
87+
//!
88+
//! This library takes these things into account, and attempts to provide an
89+
//! interface which will let those who don't care so much about the intricacies
90+
//! of color still use colors correctly, while also allowing the advanced user
91+
//! a high degree of flexibility in how they use it.
92+
//!
4693
//! # Transparency
4794
//!
4895
//! There are many cases where pixel transparency is important, but there are

0 commit comments

Comments
 (0)