Color.Conversion.Oklab
(Color v0.12.1)
Copy Markdown
Pure math for the Oklab perceptual color space, published by Björn Ottosson in 2020 (https://bottosson.github.io/posts/oklab/).
Oklab is defined relative to CIE XYZ under the D65 reference white
with Y on the [0, 1] scale. If you have an XYZ tagged with a
different illuminant, chromatically adapt it to D65 before using
these functions — they do not adapt automatically.
Note that Ottosson's published matrices use an implicit D65 of
approximately (0.9505, 1.0, 1.0883) — the Z component differs
from Lindbloom's published D65 (1.08883) by about 5 × 10⁻⁴.
This is intrinsic to the Oklab matrices and not a numerical bug.
Round-tripping an XYZ through Oklab and back preserves the value
to roughly 1 × 10⁻⁷.
The pipeline is:
XYZ ──M1──▶ LMS ──∛──▶ LMS' ──M2──▶ Oklabwith M1 the D65 Hunt-Pointer-Estevez-like matrix and M2 the final
linear projection. The functions here are the inverse of each other
to double precision.
Summary
Functions
Converts Oklab {L, a, b} to cylindrical Oklch {L, C, h}.
Converts an Oklab {L, a, b} triple to CIE XYZ (D65, Y ∈ [0, 1]).
Converts cylindrical Oklch {L, C, h} to Oklab {L, a, b}.
Converts a CIE XYZ triple (D65, Y ∈ [0, 1]) to an Oklab {L, a, b}.
Functions
Converts Oklab {L, a, b} to cylindrical Oklch {L, C, h}.
The hue h is returned in degrees in the range [0, 360).
Arguments
oklabis an{L, a, b}tuple.
Returns
- An
{L, C, h}tuple.
Examples
iex> Color.Conversion.Oklab.oklab_to_oklch({0.5, 0.0, 0.0})
{0.5, 0.0, 0.0}
Converts an Oklab {L, a, b} triple to CIE XYZ (D65, Y ∈ [0, 1]).
Arguments
oklabis an{L, a, b}tuple.
Returns
- An
{X, Y, Z}tuple.
Examples
iex> {x, y, z} = Color.Conversion.Oklab.oklab_to_xyz({1.0, 0.0, 0.0})
iex> {Float.round(x, 4), Float.round(y, 4), Float.round(z, 4)}
{0.9505, 1.0, 1.0883}
Converts cylindrical Oklch {L, C, h} to Oklab {L, a, b}.
Arguments
oklchis an{L, C, h}tuple wherehis in degrees.
Returns
- An
{L, a, b}tuple.
Examples
iex> Color.Conversion.Oklab.oklch_to_oklab({0.5, 0.0, 0.0})
{0.5, 0.0, 0.0}
Converts a CIE XYZ triple (D65, Y ∈ [0, 1]) to an Oklab {L, a, b}.
Arguments
xyzis an{X, Y, Z}tuple relative to the D65 reference white.
Returns
- An
{l, a, b}tuple whereLis perceptual lightness (0 for black, 1 for the reference white) anda/bare green-red / blue-yellow opponent axes.
Examples
iex> {l, a, b} = Color.Conversion.Oklab.xyz_to_oklab({0.95047, 1.0, 1.08883})
iex> {Float.round(l, 3), abs(a) < 1.0e-4, abs(b) < 1.0e-4}
{1.0, true, true}