semmixcolor and perception

Gamma correction and color management

A value of 128 in an image file does not mean half the light. It means about 22%. That gap is gamma. Understanding it explains why downscaled photos get darker, why gradients have a muddy middle, and why the same file looks different on two screens.

Where gamma came from

A CRT tube was nonlinear: the brightness of the spot grew roughly as the voltage raised to a power of 2.2 to 2.5. Television signals were therefore encoded "in advance", raised to the inverse power, so that the screen would emit light proportionally.

CRTs are gone, but gamma stayed, because it turned out to be useful for a second reason. The eye is far more sensitive to differences in dark tones than in light ones. Gamma encoding spreads the 256 available 8-bit levels roughly evenly in perception: many steps in the shadows, fewer in the highlights. Linear 8-bit storage would show visible banding in dark areas and waste levels in bright ones.

The sRGB curve

sRGB does not use a pure power law but a curve made of a linear segment near black and a 2.4 power. Overall it resembles a 2.2 power:

decoding (file value → light), c in 0..1: c_lin = c / 12.92 if c ≤ 0.04045 c_lin = ((c + 0.055) / 1.055)^2.4 otherwise encoding (light → file value): c = 12.92 · c_lin if c_lin ≤ 0.0031308 c = 1.055 · c_lin^(1/2.4) - 0.055 otherwise
File value (0..255)Light (linear)Perceived lightness L*
00%0
321.4%12.3
645.1%27.1
9611.7%40.7
12821.6%53.6
16035.2%65.9
19252.7%77.7
22474.5%89.2
255100%100

The table shows the point of the encoding: 128 is only 21.6% of the light, but to the eye (L* = 53.6) it is already about halfway from black to white. File values are closer to what we see than to how much light there is.

The most common mistake: computing on encoded values

Blending, blurring, resizing and transparency are operations on light. Done directly on sRGB values, they give wrong results:

The correct order is always the same: decode to linear light, do the operation, encode back. The same decoding is the first step of converting RGB to CIE XYZ.

Color management

Gamma is only one property of a device. Screens also differ in their primaries and white point, and a printer has a completely different gamut than a monitor. Color management makes the same color look the same across devices, as far as physics allows.

It works through ICC profiles. Every device or color space (sRGB, Adobe RGB, Display P3, a specific printer on a specific paper) has a profile that describes how its values relate to device-independent color. Conversion always goes through an intermediate space (the PCS, profile connection space), which is CIELAB or CIE XYZ with a D50 white:

source values → source profile → PCS (Lab / XYZ, D50) → destination profile → destination values

When source colors do not fit in the destination gamut, the profile applies one of four rendering intents:

A screen profile only makes sense if the screen is calibrated. Calibrating with a colorimeter sets gamma, white point and brightness, then builds a profile describing how the screen actually reproduces color.