﻿@%H1DIR%snibgoim.inc

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

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.

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

## CMY

Cyan, Magenta, Yellow.

## CMYK

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

## DisplayP3

@%H1DIR%DisplayP3.txt

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

## HCL

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

## HCLp

A projected form of HCL.

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

## HSB

HSB and HSV seem to be equivalent.

@%H1DIR%HSI.txt

## HSL

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

## HSV

HSB and HSV seem to be equivalent.

## HWB

Hue, Whiteness, Blackness.

## Jzazbz

@%H1DIR%Jzazbz.txt

## Lab

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

## LCH

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

LCH and LCHab appear to be identical.

## LCHab

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

LCH and LCHab appear to be identical.

## LCHuv

The cylindrical representation of CIELUV

## LinearGray

@%H1DIR%LinearGray.txt

## LMS

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

See Wikipedia: LMS.

@%H1DIR%Log.txt

## Luv

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

But it is reversible.

@%H1DIR%OHTA.txt

## ProPhoto

@%H1DIR%ProPhoto.txt

## Rec601YCbCr

@%H1DIR%Rec601YCbCr.txt

## Rec709YCbCr

@%H1DIR%Rec709YCbCr.txt

@%H1DIR%RGB.txt

## scRGB

See Wikipedia: scRGB.

## sRGB

See Wikipedia: sRGB.

## Transparent

The firsts three rows are identical to those of sRGB.

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

@%H1DIR%xyY.txt

## YDbDr

Used in the SECAM analog terrestrial colour television broadcasting standard.

See Wikipedia: YDbDr.

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

## 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 18180.6 0.277418
LinearGray 18074 0.275792
YCC 7064.12 0.107792
Rec601YCbCr 8.19604 0.000125063
YDbDr 8.145 0.000124285
YPbPr 8.14499 0.000124285
YCbCr 8.14499 0.000124285
YUV 8.14498 0.000124284
YIQ 8.14497 0.000124284
Rec709YCbCr 1.66887 2.54654e-05
Log 1.26421 1.92907e-05
OHTA 1.02106 1.55804e-05
Jzazbz 0.291991 4.4555e-06
LCH 0.286541 4.37233e-06
LCHab 0.286541 4.37233e-06
LCHuv 0.286538 4.37229e-06
ProPhoto 0.286533 4.37221e-06
xyY 0.286532 4.3722e-06
Lab 0.286531 4.37218e-06
CIELab 0.286531 4.37218e-06
LMS 0.286531 4.37218e-06
XYZ 0.28653 4.37217e-06
DisplayP3 0.28653 4.37216e-06
Luv 0.286529 4.37216e-06
HSL 0.286509 4.37184e-06
HSV 0.286507 4.37181e-06
HSB 0.286507 4.37181e-06
HWB 0.286506 4.3718e-06
HCLp 0.286502 4.37175e-06
HCL 0.286502 4.37174e-06
HSI 0.286501 4.37173e-06
Transparent 0.2865 4.37172e-06
sRGB 0.2865 4.37172e-06
scRGB 0.2865 4.37172e-06
RGB 0.2865 4.37172e-06
CMYK 0.2865 4.37172e-06
CMY 0.2865 4.37172e-06

## Scripts

### colSpace.bat

```rem Makes ckbkColSp.h1
@rem
@rem Updated:
@rem   25-September-2022 for IM v7.
@rem

set ww=100
set hh=100

setlocal enabledelayedexpansion

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

"%IMG7%magick" -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"\(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    /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\)"

"%IMG7%magick" -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

```@rem
@rem Updated:
@rem   25-September-2022 for IM v7.
@rem

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

"%IMG7%magick" -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
)

"%IMG7%magick" ^
%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

"%IMG7%magick" -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
)

"%IMG7%magick" ^
%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

"%IMG7%magick" -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
)

"%IMG7%magick" ^
%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

"%IMG7%magick" ^
%colspc%_A.png ^
%colspc%_B.png ^
%colspc%_C.png ^
-append ^
%colspc%.png

"%IMG7%magick" ^
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.
@rem
@rem Updated:
@rem   5-November-2022 for IM v7.
@rem

setlocal

if "%IX%"=="" set IX=%IMG7%

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

"%IX%magick" -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%magick" %SRC% -colorspace %%a -colorspace sRGB x.png

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

"%IX%magick" 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.

```Version: ImageMagick 7.1.0-49 Q16-HDRI x64 7a3f3f1:20220924 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
Features: Cipher DPC HDRI OpenCL
Delegates (built-in): bzlib cairo freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib
Compiler: Visual Studio 2022 (193331630)```

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.