Bridges the Color library and libvips
pixel arguments.
Every libvips operation that takes a color (background, fill, draw,
flatten, embed, …) ultimately wants a flat list of numbers in the
interpretation, value range, and band layout of the image it is
operating on. This module owns that conversion so that callers can
pass user-friendly inputs (atoms, hex strings, Color.* structs,
numeric lists) without worrying about whether the target image is
sRGB, Lab, scRGB, CMYK, or 16-bit.
Example
iex> {:ok, image} = Image.new(2, 2, color: :black)
iex> Image.Pixel.to_pixel(image, :red)
{:ok, [255, 0, 0]}
iex> {:ok, image} = Image.new(2, 2, color: :black)
iex> {:ok, lab_image} = Image.to_colorspace(image, :lab)
iex> {:ok, [l, a, b]} = Image.Pixel.to_pixel(lab_image, :red)
iex> {Float.round(l, 2), Float.round(a, 2), Float.round(b, 2)}
{53.24, 80.09, 67.2}
Summary
Functions
A defguard that loosely matches things that look like a pixel input.
The maximum opacity value (255).
The minimum opacity value (0).
Converts a color to a pixel matching the interpretation and band
layout of image.
Same as to_pixel/3, but raises on error.
Resolves a color input to an sRGB pixel [r, g, b] (or
[r, g, b, a]) with channels in 0..255, regardless of any
image context.
Same as to_srgb/1, but raises on error.
Returns a transparency value in 0..255 where 0 is transparent
and 255 is opaque.
Types
Anything that to_pixel/3 knows how to turn into a pixel.
This includes any input accepted by Color.new/2 (a Color.*
struct, a numeric list of length 3..5, a hex string, a CSS named
color string or atom), plus the Image-specific transparency aliases
:none, :transparent, and :opaque.
@type transparency() :: :none | :transparent | :opaque | 0..255 | float()
A transparency value.
:noneand:transparentare equivalent to0(fully transparent).:opaqueis equivalent to255(fully opaque).- An integer in
0..255is used as-is. - A float in
0.0..1.0is scaled to0..255.
Functions
A defguard that loosely matches things that look like a pixel input.
This is intentionally permissive — it accepts anything that might
be a color (struct, numeric list, atom that isn't a boolean,
binary). Actual validation happens in to_pixel/3.
Use this in function-head guards where you need to dispatch a color
argument away from an image argument (the Image.if_then_else/4
pattern).
@spec max_opacity() :: 255
The maximum opacity value (255).
@spec min_opacity() :: 0
The minimum opacity value (0).
@spec to_pixel( image :: Vix.Vips.Image.t() | Vix.Vips.MutableImage.t(), color :: t(), options :: Keyword.t() ) :: {:ok, [number()]} | {:error, String.t()}
Converts a color to a pixel matching the interpretation and band
layout of image.
Arguments
imageis the targetVix.Vips.Image.t/0. Its interpretation and band count determine the output shape and value range.coloris anythingColor.new/2accepts: aColor.*struct, a list of 3/4/5 numbers, a hex string ("#ff0000","#f80","#ff000080"), a CSS named color ("rebeccapurple",:misty_rose), or one of Image's transparency aliases (:none,:transparent,:opaque).optionsis a keyword list — see below.
Options
:alpha— if the target image has an alpha band, force this transparency. Accepts any valuetransparency/1accepts. If unset, the input color's own alpha is used (or full opacity if none).:intent— passed through toColor.convert/3. One of:relative_colorimetric(default),:absolute_colorimetric,:perceptual, or:saturation.
Returns
{:ok, [number(), ...]}— a flat list of numbers in the band order and pixel range that the image's interpretation expects.{:error, reason}.
Notes
For 8-bit interpretations (
:srgb,:rgb,:cmyk,:hsv,:bw) the output is integers in0..255.For 16-bit interpretations (
:rgb16,:grey16) the output is integers in0..65535.For float interpretations (
:scrgb,:lab,:lch, etc.) the output is floats in the natural range of that space.The output band count matches
Vix.Vips.Image.bands/1exactly. Alpha is appended when the image has an alpha band, and stripped when it does not.1-band (
:bw,:grey16) images receive a single luminance channel computed from the perceptually-uniformColor.LabL*.
Examples
iex> {:ok, image} = Image.new(2, 2, color: :black)
iex> Image.Pixel.to_pixel(image, :red)
{:ok, [255, 0, 0]}
iex> {:ok, image} = Image.new(2, 2, color: [0, 0, 0, 255])
iex> Image.Pixel.to_pixel(image, :red)
{:ok, [255, 0, 0, 255]}
iex> {:ok, image} = Image.new(2, 2, color: [0, 0, 0, 255])
iex> Image.Pixel.to_pixel(image, :red, alpha: 0.5)
{:ok, [255, 0, 0, 128]}
iex> {:ok, image} = Image.new(2, 2, color: :black)
iex> Image.Pixel.to_pixel(image, "#ff000080")
{:ok, [255, 0, 0]}
@spec to_pixel!(image :: Vix.Vips.Image.t(), color :: t(), options :: Keyword.t()) :: [number()]
Same as to_pixel/3, but raises on error.
@spec to_srgb(color :: t()) :: {:ok, [0..255]} | {:error, Image.Error.t() | term()}
Resolves a color input to an sRGB pixel [r, g, b] (or
[r, g, b, a]) with channels in 0..255, regardless of any
image context.
Use this for callers that need sRGB output specifically — for
example SVG renderers — rather than the interpretation of an
image. For image-aware encoding use to_pixel/3.
Arguments
coloris anythingColor.new/2accepts, plus the transparency aliases.
Returns
{:ok, [0..255, 0..255, 0..255]}or{:ok, [0..255, 0..255, 0..255, 0..255]}if the source had an alpha channel.{:error, reason}.
Examples
iex> Image.Pixel.to_srgb(:red)
{:ok, [255, 0, 0]}
iex> Image.Pixel.to_srgb("#ff000080")
{:ok, [255, 0, 0, 128]}
iex> Image.Pixel.to_srgb(%Color.Lab{l: 53.24, a: 80.09, b: 67.20})
{:ok, [255, 0, 0]}
@spec to_srgb!(color :: t()) :: [0..255]
Same as to_srgb/1, but raises on error.
@spec transparency(value :: transparency()) :: {:ok, 0..255} | {:error, Image.Error.t()}
Returns a transparency value in 0..255 where 0 is transparent
and 255 is opaque.
Arguments
transparencyis one of:The atoms
:none,:transparent, or:opaque.An integer in
0..255.A float in
0.0..1.0.
Returns
{:ok, 0..255}or{:error, reason}.
Examples
iex> Image.Pixel.transparency(:opaque)
{:ok, 255}
iex> Image.Pixel.transparency(:transparent)
{:ok, 0}
iex> Image.Pixel.transparency(0.5)
{:ok, 128}
iex> Image.Pixel.transparency(200)
{:ok, 200}