Color Space and Interpolation

Last updated 23 March 2015

The color space used for combining colors or interpolating between color values greatly effects the resulting colors. Most software today uses the sRGB color space. Blending/interpolating in this color space usually leads to unexpected results. A linear color space is much preferred. But support for linear color spaces is pretty rare. Both Gimp and Photoshop support linear color spaces when the color depth is 16 or 32 bits. The SVG standard includes two attributes for requesting that color operations be performed in a linear colors space: 'color-interpolation' and 'color-interpolation-filters'. Unfortunately, nobody implements the former property (there is a lack of support in graphics libraries). The new Compositing and Blending Level 1 specification doesn't even mention color spaces. The linear option for the 'color-interpolation-filters' property is implemented by all browsers since that is the default (and it is relatively easy to implement).

Color spaces are important for color operations in a number of areas:

Blending/Compositing

Blending in the sRGB color space produces unexpected dark borders between regions being blended.

Various happy/sad faces showing the effects of incorrect blending (sRGB/sad faces) and correct blending (linear/happy faces).

Top row: blending using the sRGB color space. Bottom row: Blending using a linear color space. The linear color space examples here rely on SVG filters.
Note: Firefox does not render the linear blending examples; Chrome does.

PNG version of previous figure.

PNG version of above figure.

On the web, the only real way to get linear blending is to use SVG filters. This is not particularly easy and browser support is flaky (as the above example demonstrates).

The video Computer Color is Broken has caused a heighten interest in this topic.

Gradients

Interpolation between color stops in gradients should be done in a linear color space. At the moment, no browser does this.

Various filters.

Different values for color-interpolation. Top: sRGB, bottom: linearRGB.

Various filters.

If these three gradients look the same, your browser does not support color-interpolation="linearRGB". Top: default behavior ("sRGB"), middle "sRGB", bottom: "linearRGB"

A real life example:

Google I/O logo.

Google I/O Logo: sRGB.

Google I/O logo.

Google I/O Logo: linearRGB.

Up/down Scaling

Up/down scaling should be done in linearRGB. If it is not, it can lead to unexpected color shifts. Here is a simple test that illustrates the problem:

Upscaling/downscaling test. The top two squares should be the same gray as the bottom right square. Note that the 1x1 bitmap image may be blurred (smoothed) by browser.
Zoom your browser window in and out to see effect.

A good discussion of this problem can be found at the Gamma error in picture scaling web site.

SVG Filters

SVG filters can also depend on the color space used. The default color space for SVG filters is linear. Most, if not all, browsers implement the 'linearRGB' value for 'color-interpolation-filters' as this is the default value.

Browsers mostly implement this consistently (after some recent work). Here is a test for a variety of filter primitives that depend on the color space used.

Various filters.

Various filter primitives with different values of "color-interpolation-filters". For each pair of squares, the one on the left uses the 'sRGB' color space, the one on the right uses the 'linearRGB' color space. A test passes if no inner square is visible.

Doing the Right Thing

Historically, the sRGB space was used for performance reasons. With more power computers and off-loading to GPU's, we should at least be able to specify that the browsers do the right thing. One interesting note is that OpenGL can convert sRGB to a linear color space for color operations with no performance loss using EXT_texture_sRGB.