Color.Gamut (Color v0.4.0)

Copy Markdown

Gamut checking and gamut mapping.

  • in_gamut?/2 — returns whether a color fits inside the given RGB working space.

  • to_gamut/3 — brings an out-of-gamut color into the working space. Two methods are provided:

    • :clip — clamp linear RGB to [0, 1]. Fast and deterministic but can visibly distort saturated colors.

    • :oklch (default) — the CSS Color 4 gamut-mapping algorithm. Converts to Oklch, then binary-searches for the highest chroma that still fits inside the destination gamut, preserving lightness and hue. This is what browsers do when rendering a color(display-p3 …) value on an sRGB display.

Examples

iex> Color.Gamut.in_gamut?(%Color.SRGB{r: 0.5, g: 0.5, b: 0.5}, :SRGB)
true

iex> Color.Gamut.in_gamut?(%Color.SRGB{r: 1.2, g: 0.5, b: -0.1}, :SRGB)
false

Summary

Functions

Returns true if the color lies inside the given RGB working space gamut (each linear channel in [0, 1] up to a small epsilon).

Brings a color inside the given RGB working space gamut.

Functions

in_gamut?(color, working_space \\ :SRGB)

@spec in_gamut?(Color.input(), Color.Types.working_space()) :: boolean()

Returns true if the color lies inside the given RGB working space gamut (each linear channel in [0, 1] up to a small epsilon).

Arguments

  • color is anything accepted by Color.new/1.

  • working_space is an atom naming an RGB working space (for example :SRGB, :P3_D65, :Rec2020). Defaults to :SRGB.

Returns

  • A boolean.

to_gamut(color, working_space \\ :SRGB, options \\ [])

@spec to_gamut(Color.input(), Color.Types.working_space(), keyword()) ::
  {:ok, struct()} | {:error, Exception.t()}

Brings a color inside the given RGB working space gamut.

Arguments

  • color is anything accepted by Color.new/1.

  • working_space is an atom naming an RGB working space. Defaults to :SRGB.

  • options is a keyword list.

Options

  • :method is :oklch (default) or :clip.

Returns

  • {:ok, %Color.SRGB{}} — for :SRGB. For other working spaces the result is the appropriate companded RGB struct (%Color.AdobeRGB{} for :Adobe, a linear %Color.RGB{} otherwise).

Examples

iex> {:ok, mapped} = Color.Gamut.to_gamut(%Color.Oklch{l: 0.9, c: 0.3, h: 30.0}, :SRGB)
iex> Color.Gamut.in_gamut?(mapped, :SRGB)
true