Colour Models

The five tc-lib-color models: grayscale, RGB, HSL, CMYK and CIE Lab, with their components, ranges and output forms

A parsed colour is an object of one of five classes. All five extend \Com\Tecnick\Color\Model and implement \Com\Tecnick\Color\Model\Template, so any of them exposes the same set of methods.

Below, each model holds #336699.

ModelEnum casegetCssColor()getPdfColor()getJsPdfColor()
GRAYColorModelType::Grayg(95)0.371920 g["G",0.371920]
RGBColorModelType::Rgbrgb(51,102,153)0.200000 0.400000 0.600000 rg["RGB",0.200000,0.400000,0.600000]
HSLColorModelType::Hslhsl(210,50%,40%)0.200000 0.400000 0.600000 rg["RGB",0.200000,0.400000,0.600000]
CMYKColorModelType::Cmykcmyk(66.6667%,33.3333%,0%,40%)0.666667 0.333333 0.000000 0.400000 k["CMYK",0.666667,0.333333,0.000000,0.400000]
LABColorModelType::Lablab(42.0081% -0.1517 -32.846)0.200000 0.400000 0.600000 rg["RGB",0.200000,0.400000,0.600000]

PDF defines device colour spaces for grayscale, RGB and CMYK. HSL and Lab convert to DeviceRGB on output, so three rows of that table repeat.

The Five Pages

ModelComponentsUsed for
Grayscaleonesingle-channel output, ink coverage, masks
RGBthreescreen output, and the hub of every conversion
HSLthreeadjusting an existing colour
CMYKfourprocess printing, spot colour alternate space
CIE Labthreedevice independence, perceptual distance

Components

ModelComponentsRangeOut of range
GRAYgray0.0 to 1.0clamped
RGBred, green, blue0.0 to 1.0clamped
HSLhue0.0 to 1.0, a fraction of a turnwrapped
HSLsaturation, lightness0.0 to 1.0clamped
CMYKcyan, magenta, yellow, key0.0 to 1.0clamped
LABlstar0.0 to 100.0clamped
LABastar, bstar-128.0 to 127.0clamped
allalpha0.0 to 1.0, default 1.0clamped

Every model carries an alpha channel and every conversion preserves it. A component the model does not define raises UnknownComponentException; a component it does define but cannot read as a number falls back to the default.

Building One

Model::create() takes a ColorModelType case or the plain type string. The enum’s backing value is the type string the model reports, so the two are interchangeable wherever a type is accepted.

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Com\Tecnick\Color\ColorModelType;
use Com\Tecnick\Color\Model;

$cmyk = Model::create(ColorModelType::Cmyk, [
    'cyan' => 0.67,
    'magenta' => 0.33,
    'yellow' => 0.0,
    'key' => 0.4,
]);

echo $cmyk->getCssColor(), "\n";
echo $cmyk->getType(), "\n";
var_dump($cmyk->getTypeEnum() === ColorModelType::Cmyk);

// the enum case and the type string are interchangeable
echo Model::create('CMYK', $cmyk->toCmykArray())->getCssColor(), "\n";
echo ColorModelType::Cmyk->value, "\n";
cmyk(67%,33%,0%,40%)
CMYK
bool(true)
cmyk(67%,33%,0%,40%)
CMYK

The model pages construct the classes directly. create() applies where the type is a variable.

Raw Values Against Formatted Ones

getArray() and getNormalizedArray() return the components as the library holds them, floats and all. getCssColor() rounds to four decimals and drops trailing zeros.

$rgb = (new \Com\Tecnick\Color\Web())->getColorObj('#336699');

$hsl = \Com\Tecnick\Color\Model::create('HSL', $rgb->toHslArray());

var_dump($hsl->getArray());
echo $hsl->getCssColor(), "\n";
array(4) {
  ["H"]=>
  float(0.5833333333333334)
  ["S"]=>
  float(0.49999999999999994)
  ["L"]=>
  float(0.4)
  ["A"]=>
  float(1)
}
hsl(210,50%,40%)

0.49999999999999994 is a binary floating point result, not a conversion error: the exact saturation of #336699 is 0.5 and the conversion arithmetic does not land on it. Compare components with a tolerance and use the CSS form for display.

getNormalizedArray($max) scales to $max for the models whose components have no natural unit, GRAY, RGB and CMYK. HSL returns degrees and fractions, and Lab returns its own ranges rounded to integers; both ignore the argument. Each model page states which.

See Also