snibgo's ImageMagick pages

Colorspace cookbook

ImageMagick can change colorspaces. We can examine the effect of a round-trip from sRGB, to another colorspace, and back, both pictorially and numerically.

The page illustrates ImageMagick "colorspaces". This IM term conflates the two concepts of "color model" and "color space". A color model determines the meaning of each channel; a colour space additionally determines the meaning of each value in each channel.

This page ignores issues of colour profiles.

Each ImageMagick colorspace is illustrated by six rows of squares.

The first group of three rows is created by a gradient within the given colourspace. The second group of three rows takes the gradient created for the sRGB colorspace, declares that to be in the named colorspace, and converts the data from that colorspace to sRGB.

In most cases, the first group of three rows is identical to the second.

Each row contains eleven squares, each of which is 100x100 pixels. In the first of the three rows, the first channel increases from 0 to 100% from left to right across the eleven squares. In the second row, the second channel is increased. In the third row, the third channel is increased.

Within each 100x100 square, the other two of the three channels are varied, starting at (0,0) in the bottom-left, increasing to (100%,100%) top-right.

In the squares in the left-most column, the pixel at bottom-left has all three channels zero. In the right-most column, the pixel at top-right has all three columns at 100%.

Put it another way: eleven squares show cross-sections of the colour cube. The next two rows slice the cube in the other two dimensions.

Some of the colorspaces are aimed at devices other than computer screens, but all the images have been converted to sRGB for displaying on computer screens. Thus, the colours you see may not represent the intended colours. In addition, two colorspaces generally don't have the same gamut: each may represent colours that can't be represented in the other. One consequence is that two colours that can be distinguished in one colorspace may translate to the same colour in sRGB.

See also:

CIELab

CIELab is designed to represent the human visual system. In particular, two equal shifts in CIELab space should be considered visually equivalent. As such, it is very useful in photographic processing.

This colorspace has three channels: L*, a* and b* (pronounced "ell star", "ay star" and "bee star"). L* is lightness. The other two channels represent both hue and saturation. a* is the axis from green-cyan (at L* = 50%, this translates to a hue of approximately 165°) through gray to red-magenta (330°). b* is the axis from blue-cyan (207°) through gray to orange (47°). These are not 180° apart, so the a*-b* plane is not simply a rotation of the standard hue. Besides, the hue varies with L*.

Colours at zero saturation (i.e. shades of gray from black to white) have a*=b*=50%.

This is identical to the ImageMagick "Lab" colorspace.

See also: Wikipedia: Lab color space.

CIELab.pngjpg
CIELab_conv.pngjpg

CMY

Cyan, Magenta, Yellow.

CMY.pngjpg
CMY_conv.pngjpg

CMYK

Leaving the K channel unset, the result is identical to the CMY colorspace.

CMYK.pngjpg
CMYK_conv.pngjpg

Gray

The first three rows attempt to set three channels, using Gray(r,g,b), although that function should take a single argument.

Visually, the first three rows are the same as the second three, but they are slightly different (RMSE=0.0011)

Gray.pngjpg
Gray_conv.pngjpg

HCL

See IM forum L in HCL is not Luminance! (my error).

HCL.pngjpg
HCL_conv.pngjpg

HCLp

A projected form of HCL.

See IM forum L in HCL is not Luminance! (my error).

HCLp.pngjpg
HCLp_conv.pngjpg

HSB

HSB and HSV seem to be equivalent.

HSB.pngjpg
HSB_conv.pngjpg

HSI

@%H1DIR%HSI.txt HSI.pngjpg
HSI_conv.pngjpg

HSL

See: Wikipedia: HSL and HSV, which also discusses the relative merits of a variety of colour models.

HSL.pngjpg
HSL_conv.pngjpg

HSV

HSB and HSV seem to be equivalent.

HSV.pngjpg
HSV_conv.pngjpg

HWB

Hue, Whiteness, Blackness.

HWB.pngjpg
HWB_conv.pngjpg

Lab

See the comments under CIELab, which is identical to Lab.

Lab.pngjpg
Lab_conv.pngjpg

LCH

Lightness, Chroma, Hue; the cylindrical form of CIELab.

LCH and LCHab appear to be identical.

LCH.pngjpg
LCH_conv.pngjpg

LCHab

Lightness, Chroma, Hue; the cylindrical form of CIELab.

LCH and LCHab appear to be identical.

LCHab.pngjpg
LCHab_conv.pngjpg

LCHuv

The cylindrical representation of CIELUV

See Wikipedia: CIELUV: Cylindrical representation.

LCHuv.pngjpg
LCHuv_conv.pngjpg

LMS

Represents long, medium and short wavelengths of light (the red, green and blue cones of human vision).

See Wikipedia: LMS.

LMS.pngjpg
LMS_conv.pngjpg

Log

@%H1DIR%Log.txt Log.pngjpg
Log_conv.pngjpg

Luv

See Wikipedia: CIELUV.

This looks very weird to me. Perhaps IM's implementation is broken.

But it is reversible.

Luv.pngjpg
Luv_conv.pngjpg

OHTA

@%H1DIR%OHTA.txt OHTA.pngjpg
OHTA_conv.pngjpg

Rec601Luma

IM has no function "Rec601Luma(a,b,c)", so we substitute "rgb(a,b,c)" for the first three rows. The result is different to the second three rows.

The first three rows are identical to the first three of Gray; the second three rows are identical to the second three of Gray.

Rec601Luma.pngjpg
Rec601Luma_conv.pngjpg

Rec601YCbCr

@%H1DIR%Rec601YCbCr.txt Rec601YCbCr.pngjpg
Rec601YCbCr_conv.pngjpg

Rec709Luma

IM has no function "Rec709Luma(a,b,c)", so we substitute "rgb(a,b,c)" for the first three rows. The result is different to the second three rows.

The first three rows are identical to the first three of Gray; the second three rows are identical to the second three of Gray.

Rec709Luma.pngjpg
Rec709Luma_conv.pngjpg

Rec709YCbCr

@%H1DIR%Rec709YCbCr.txt Rec709YCbCr.pngjpg
Rec709YCbCr_conv.pngjpg

RGB

@%H1DIR%RGB.txt RGB.pngjpg
RGB_conv.pngjpg

scRGB

See Wikipedia: scRGB.

scRGB.pngjpg
scRGB_conv.pngjpg

sRGB

See Wikipedia: sRGB.

sRGB.pngjpg
sRGB_conv.pngjpg

Transparent

The firsts three rows are identical to those of sRGB.

The second three rows are clearly different (RMSE=0.204) to the first.

Transparent.pngjpg
Transparent_conv.pngjpg

XYZ

See Wikipedia: CIE 1931 color space.

XYZ.pngjpg
XYZ_conv.pngjpg

xyY

@%H1DIR%xyY.txt xyY.pngjpg
xyY_conv.pngjpg

YCbCr

See also: Wikipedia: YCbCr.

YCbCr.pngjpg
YCbCr_conv.pngjpg

YDbDr

Used in the SECAM analog terrestrial colour television broadcasting standard.

See Wikipedia: YDbDr.

YDbDr.pngjpg
YDbDr_conv.pngjpg

YCC

This colorspace doesn't seem to be reversible.

convert in.png -colorspace YCC -colorspace sRGB out.png

gives out.png darker than in.png.

YCC.pngjpg
YCC_conv.pngjpg

YIQ

See also: Wikipedia: YIQ.

YIQ.pngjpg
YIQ_conv.pngjpg

YPbPr

See also: Wikipedia: YPbPr.

YPbPr.pngjpg
YPbPr_conv.pngjpg

YUV

See also: Wikipedia: YUV.

YUV.pngjpg
YUV_conv.pngjpg

Numerical round-trip

We can compare numerical results of each round-trip.

Where the first column is near 1, the round trip is successful.

Round trips for monochrome colorspaces are expected to have a large difference.

call %PICTBAT%colSpRndTrip
Colorspace Integer Float
Gray 18181.7 0.277435
Rec709Luma 18181.7 0.277435
Rec601Luma 16972 0.258977
YCC 7191.13 0.10973
YDbDr 5912.42 0.0902177
LCHuv 937.163 0.0143002
YUV 265.687 0.00405413
YIQ 156.837 0.00239318
XYZ 152.622 0.00232887
LMS 71.7158 0.00109431
LCHab 63.9958 0.000976513
LCH 63.9958 0.000976513
Rec601YCbCr 8.19112 0.000124989
YCbCr 8.15981 0.000124511
YPbPr 8.15981 0.000124511
xyY 2.69261 4.10866e-005
Luv 1.69933 2.59302e-005
Rec709YCbCr 1.64528 2.51054e-005
Lab 1.43594 2.1911e-005
CIELab 1.43594 2.1911e-005
Log 1.28087 1.95448e-005
scRGB 1.11803 1.70601e-005
RGB 1.11803 1.70601e-005
OHTA 0.995072 1.51838e-005
HSL 0.745473 1.13752e-005
HSI 0.675326 1.03048e-005
HCLp 0.644634 9.83648e-006
HCL 0.612231 9.34205e-006
HSB 0.583683 8.90643e-006
HSV 0.583683 8.90643e-006
HWB 0.578735 8.83093e-006
Transparent 0 0
sRGB 0 0
CMYK 0 0
CMY 0 0

Scripts

The following Windows bat scripts generated this page:

colSpace.bat

rem Makes ckbkColSp.h1

set ww=100
set hh=100

setlocal enabledelayedexpansion

set/A wwm1=%ww%-1
set/A hhm1=%hh%-1

"%IM%convert" -list colorspace >cs.lis
type cs.lis

rem sRGB is used for the second group of all the color spaces, so create it first.
set colspc=sRGB
call %PICTBAT%oneColSp

rem goto skip
for /F %%a in (cs.lis) do (
  set colspc=%%a
  call %PICTBAT%oneColSp
)
:skip


cEcho /ockbkColsp.h1 /X /s"@%%H1DIR%%snibgoim.inc"
cEcho /OckbkColsp.h1 /X /s"\(h1\)Colorspace cookbook\(/h1\)"
cEcho /OckbkColsp.h1 /X /s"\(p\)ImageMagick can change colorspaces. We can examine the effect of a round-trip from sRGB, to another colorspace, and back, both pictorially and numerically.\(/p\)"

cEcho /OckbkColsp.h1 /X /s"@%%H1DIR%%colspace.txt"

for /F %%a in (cs.lis) do (
  @set colspc=%%a
  @rem cEcho /OckbkColsp.h1 /X /s"\(a name=\q!colspc!\q\)"
  @rem cEcho /OckbkColsp.h1 /X /s"\(h2\)!colspc!\(/h2\)"
  @rem cEcho /OckbkColsp.h1 /X /s"\(/a\)"

  @rem Tidy wants tag "a" inside "h2".
  @cEcho /OckbkColsp.h1 /X /s"\(h2\)\(a name=\q!colspc!\q\)!colspc!\(/a\)\(/h2\)"

  @cEcho /OckbkColsp.h1 /X /s"@%%H1DIR%%!colspc!.txt"
  @cEcho /OckbkColsp.h1 /X /s"\(img class=\qcenter\q src=\q!colspc!.pngjpg\q /\)"
  @cEcho /OckbkColsp.h1 /X /s"\(br /\)"
  @cEcho /OckbkColsp.h1 /X /s"\(img class=\qcenter\q src=\q!colspc!_conv.pngjpg\q /\)"
  @cEcho /OckbkColsp.h1 /X /s"\(br /\)"
)

cEcho /OckbkColsp.h1 /X /s"\(hr /\)"
cEcho /OckbkColsp.h1 /X /s"\(h2\)Numerical round-trip\(/h2\)"

cEcho /OckbkColsp.h1 /X /s"\(p\)We can compare numerical results of each round-trip.\(/p\)"

cEcho /OckbkColsp.h1 /X /s"\(p\)Where the first column is near 1, the round trip is successful.\(/p\)"

cEcho /OckbkColsp.h1 /X /s"\(p\)Round trips for monochrome colorspaces are expected to have a large difference.\(/p\)"

cEcho /OckbkColsp.h1 /X /s"\(code\)\ncall %%PICTBAT%%colSpRndTrip\n\(/code\)\n"
cEcho /OckbkColsp.h1 /X /s"@csrt.htm"

cEcho /OckbkColsp.h1 /X /s"\(hr /\)"
cEcho /OckbkColsp.h1 /X /s"\(h2\)Scripts\(/h2\)"

cEcho /OckbkColsp.h1 /X /s"\(p\)The following Windows bat scripts generated this page:\(/p\)"

cEcho /OckbkColsp.h1 /X /s"\(h3\)colSpace.bat\(/h3\)"
cEcho /OckbkColsp.h1 /X /s"\(pre\)"
cEcho /OckbkColsp.h1 /X /s"@%%PICTBAT%%colSpace.bat"
cEcho /OckbkColsp.h1 /X /s"\(/pre\)"

cEcho /OckbkColsp.h1 /X /s"\(h3\)oneColSp.bat\(/h3\)"
cEcho /OckbkColsp.h1 /X /s"\(pre\)"
cEcho /OckbkColsp.h1 /X /s"@%%PICTBAT%%oneColSp.bat"
cEcho /OckbkColsp.h1 /X /s"\(/pre\)"

cEcho /OckbkColsp.h1 /X /s"\(h3\)colSpRndTrip.bat\(/h3\)"
cEcho /OckbkColsp.h1 /X /s"\(pre\)"
cEcho /OckbkColsp.h1 /X /s"@%%PICTBAT%%colSpRndTrip.bat"
cEcho /OckbkColsp.h1 /X /s"\(/pre\)"

cEcho /OckbkColsp.h1 /X /s"\(hr /\)"

cEcho /OckbkColsp.h1 /X /f\r /s"\(p\)To create this page, run \(tt\)"
cEcho /OckbkColsp.h1    /f\r /s"%%PICTBAT%%colSpace.bat"
cEcho /OckbkColsp.h1 /X      /s"\(/tt\) to create the images and ckbkColSp.h1, then \(tt\)procH1 ckbkColSp\(/tt\).\(/p\)"

"%IMG%convert" -version>imversion.txt
cEcho /OckbkColsp.h1 /X /s"\(p\)Images and data on this page were created using:\(/p\)"
cEcho /OckbkColsp.h1 /X /s"\(pre\)"
cEcho /OckbkColsp.h1 /X /s"@imversion.txt"
cEcho /OckbkColsp.h1 /X /s"\(/pre\)"

cEcho /OckbkColsp.h1 /X /s"@%%H1DIR%%snibgocr.inc"

cEcho /OckbkColsp.h1 /X /s"\(^!--Page-version v1.1 20-Feb-2014--\)"
cEcho /OckbkColsp.h1 /X /s"\(^!--Trailer-img sRGB.png --\)"

rem call %PICTBAT%cookbook.bat

endlocal

oneColSp.bat

set func=%colspc%

rem if "%func%"=="LMS" set func=rgb
if "%func%"=="OHTA" set func=rgb
if "%func%"=="Rec601Luma" set func=rgb
if "%func%"=="Rec709Luma" set func=rgb

set func=rgb


for /l %%a in (0,10,100) do (
set /A num=%%a/10

"%IM%convert" -size 100x100 xc: ^
  -colorspace %colspc% ^
  -sparse-color Bilinear "0.5,0.5 %func%(%%a%%,100%%,0) %wwm1%,0.5 %func%(%%a%%,100%%,100%%) 0.5,%hhm1% %func%(%%a%%,0,0) %wwm1%,%hhm1% %func%(%%a%%,0,100%%)" ^
  -colorspace sRGB ^
  %colspc%_!num!.png
)

"%IM%convert" ^
  %colspc%_0.png %colspc%_1.png %colspc%_2.png %colspc%_3.png %colspc%_4.png ^
  %colspc%_5.png %colspc%_6.png %colspc%_7.png %colspc%_8.png %colspc%_9.png ^
  %colspc%_10.png ^
  +append ^
  %colspc%_A.png


for /l %%a in (0,10,100) do (
set /A num=%%a/10

"%IM%convert" -size 100x100 xc: ^
  -colorspace %colspc% ^
  -sparse-color Bilinear "0.5,0.5 %func%(100%%,%%a%%,0) %wwm1%,0.5 %func%(100%%,%%a%%,100%%) 0.5,%hhm1% %func%(0,%%a%%,0) %wwm1%,%hhm1% %func%(0,%%a%%,100%%)" ^
  -colorspace sRGB ^
  %colspc%_!num!.png
)

"%IM%convert" ^
  %colspc%_0.png %colspc%_1.png %colspc%_2.png %colspc%_3.png %colspc%_4.png ^
  %colspc%_5.png %colspc%_6.png %colspc%_7.png %colspc%_8.png %colspc%_9.png ^
  %colspc%_10.png ^
  +append ^
  %colspc%_B.png


for /l %%a in (0,10,100) do (
set /A num=%%a/10

"%IM%convert" -size 100x100 xc: ^
  -colorspace %colspc% ^
  -sparse-color Bilinear "0.5,0.5 %func%(100%%,0,%%a%%) %wwm1%,0.5 %func%(100%%,100%%,%%a%%) 0.5,%hhm1% %func%(0,0,%%a%%) %wwm1%,%hhm1% %func%(0,100%%,%%a%%)" ^
  -colorspace sRGB ^
  %colspc%_!num!.png
)

"%IM%convert" ^
  %colspc%_0.png %colspc%_1.png %colspc%_2.png %colspc%_3.png %colspc%_4.png ^
  %colspc%_5.png %colspc%_6.png %colspc%_7.png %colspc%_8.png %colspc%_9.png ^
  %colspc%_10.png ^
  +append ^
  %colspc%_C.png

"%IM%convert" ^
  %colspc%_A.png ^
  %colspc%_B.png ^
  %colspc%_C.png ^
  -append ^
  %colspc%.png

"%IM%convert" ^
  sRGB.png ^
  -set colorspace %colspc% ^
  -colorspace sRGB ^
  %colspc%_conv.png


del %colspc%_0.png %colspc%_1.png %colspc%_2.png %colspc%_3.png %colspc%_4.png
del %colspc%_5.png %colspc%_6.png %colspc%_7.png %colspc%_8.png %colspc%_9.png
del %colspc%_10.png ^
del %colspc%_A.png %colspc%_B.png %colspc%_C.png

colSpRndTrip.bat

rem Tests the round-trip capabilities of colorspaces.

setlocal

if "%IX%"=="" set IX=%IM%

"%IX%convert" hald:8 h8.miff

"%IX%convert" -list colorspace >%TEMP%\cs2.lis

set SRC=\pictures\20130525\sm.tiff
set SRC=h8.miff

del csrt.csv

for /F %%a in (%TEMP%\cs2.lis) do (
  "%IX%convert" %SRC% -colorspace %%a -colorspace sRGB x.png

  rem "%IX%compare" -metric RMSE %SRC% -format %%a x.png NULL:

  "%IX%compare" -metric RMSE %SRC% x.png NULL: 2>>csrt.csv
  cEcho /Ocsrt.csv /s" %%a"
)

cSort /icsrt.csv /ocsrt.csv /k0 /f" " /r

del %TEMP%\cs2.lis

type csrt.csv

chStrs /icsrt.csv /f" (" /t", "
chStrs /icsrt.csv /f") " /t", "
cPrefix /icsrt.csv /t"Integer,Float,Colorspace"
cProject /icsrt.csv /h /kColorspace,Integer,Float

type csrt.csv

call csv2tab csrt

To create this page, run %PICTBAT%colSpace.bat to create the images and ckbkColSp.h1, then procH1 ckbkColSp.

Images and data on this page were created using:

Version: ImageMagick 6.9.0-0 Q16 x64 2014-11-14 http://www.imagepyright (C) 1999-2015 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP 
Delegates (built-in): bzlib cairo freetype jng jp2 jpeg lcms lqr openexr pangocairo png ps rsvg tiff webp xml zlib

This page, including the images, is my copyright. Anyone is permitted to use or adapt any of the code, scripts or images for any purpose, including commercial use.

Anyone is permitted to re-publish this page, but only for non-commercial use.

Anyone is permitted to link to this page, including for commercial use.


Page version v1.1 20-Feb-2014.

Page created 14-Oct-2015 06:04:34.

Copyright © 2015 Alan Gibson.