Image.YUV (image v0.71.0)

Copy Markdown View Source

Functions to convert from/to YUV (YCbCr) encoding and BT.601/BT.709 colorspaces and sRGB images.

The following YUV (YCbCr) binary formats are supported:

  • Planar frame types only (not packed frames).

  • 4:4:4, 4:2:2 and 4:2:0 encodings.

  • BT.601 and BT.709 colorspaces.

  • :limited (studio-swing, the default) and :full (PC/JPEG) signal ranges. See Image.YUV.yuv_range/0.

Performance profiling indicates this implementation is not suitable for real time frame processing of YUV images.

Summary

Types

YUV colorspace

YUV encoding

YUV data as a three-element list of binaries

YUV signal range.

Functions

Deocdes a raw YUV binary into [y, u, v] planes where each plane is a binary.

Encodes an image that is in a YUV colorspace to raw YUV data that is a list of the three planes, each a binary.

Converts the raw YUV data in a .yuv file into an RGB image.

Convert an image in an YUV colorspace and convert it to RGB colorspace.

Takes the [y, u, v] planes and converts them to an RGB image.

Converts an image to raw YUV data as a binary.

Returns the list of YUV → RGB conversion colorspaces supported by this module.

Returns the list of YUV chroma-subsampling encodings supported by this module.

Returns the list of YUV signal ranges supported by this module.

Types

yuv_colorspace()

@type yuv_colorspace() :: :bt601 | :bt709

YUV colorspace

yuv_encoding()

@type yuv_encoding() :: :C444 | :C422 | :C420

YUV encoding

yuv_list()

@type yuv_list() :: [binary()]

YUV data as a three-element list of binaries

yuv_range()

@type yuv_range() :: :limited | :full

YUV signal range.

  • :limited (also called studio-swing or TV range) encodes luma in 16..235 and chroma in 16..240. This is the convention used by most video formats (including YUV4MPEG) and is the default.

  • :full (also called PC range or JPEG range) encodes luma and chroma across the whole 0..255 range.

The range must match on encode and decode; mixing them shifts colors (a full-range signal decoded as limited-range washes toward grey, and vice versa).

Functions

decode(binary, width, height, atom)

(since 0.41.0)

Deocdes a raw YUV binary into [y, u, v] planes where each plane is a binary.

Arguments

  • binary is a binary representation of a YUV image.

  • width is the width of the image encoded in yuv.

  • height is the height of the image encoded in yuv.

  • encoding is one of :C444, :C422 or :C420 representing how yuv is encoded.

Returns

  • {:ok, [y, u, v]} or

  • {:error, reason}.

Examples

iex> binary = :binary.copy(<<128>>, 8 * 8 + 2 * (4 * 4))
iex> {:ok, [y, u, v]} = Image.YUV.decode(binary, 8, 8, :C420)
iex> {byte_size(y), byte_size(u), byte_size(v)}
{64, 16, 16}

iex> {:error, %Image.Error{}} = Image.YUV.decode(<<1, 2, 3>>, 8, 8, :C444)

encode(image, atom)

(since 0.41.0)
@spec encode(image :: Vix.Vips.Image.t(), encoding :: yuv_encoding()) ::
  {:ok, yuv_list()} | {:error, Image.error()}

Encodes an image that is in a YUV colorspace to raw YUV data that is a list of the three planes, each a binary.

The data is always written in a planar format.

Arguments

Returns

  • {:ok, [y, u, v]} or

  • {:error, Image.error()}.

Examples

iex> yuv_image = Image.new!(8, 8, color: [128, 128, 128])
iex> {:ok, [y, u, v]} = Image.YUV.encode(yuv_image, :C422)
iex> {byte_size(y), byte_size(u), byte_size(v)}
{64, 32, 32}

new_from_binary(binary, width, height, encoding, colorspace \\ :bt601, range \\ :limited)

(since 0.41.0)
@spec new_from_binary(
  binary :: binary(),
  width :: pos_integer(),
  height :: pos_integer(),
  encoding :: yuv_encoding(),
  colorspace :: yuv_colorspace(),
  range :: yuv_range()
) :: {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}

Converts raw YUV data into an RGB image.

The data is assumed, and required to be in:

  • Planar format
  • 8-bit color depth

Arguments

  • binary is raw YUV data as a binary.

  • width is the width of the image encoded in the YUV data.

  • height is the height of the image encoded in the YUV data.

  • encoding is one of :C444, :C422 or :C420.

  • colorspace is one of :bt601 (the default) or :bt709.

  • range is one of :limited (the default) or :full. See Image.YUV.yuv_range/0. It must match the range used when the data was encoded.

Returns

  • {:ok, rgb_image} or

  • {:error, reason}.

Examples

iex> binary = :binary.copy(<<128>>, 3 * 8 * 8)
iex> {:ok, image} = Image.YUV.new_from_binary(binary, 8, 8, :C444)
iex> {Image.shape(image), Image.colorspace(image)}
{{8, 8, 3}, :srgb}

new_from_file(path, width, height, encoding, colorspace \\ :bt601, range \\ :limited)

(since 0.41.0)
@spec new_from_file(
  path :: Path.t(),
  width :: pos_integer(),
  height :: pos_integer(),
  encoding :: yuv_encoding(),
  colorspace :: yuv_colorspace(),
  range :: yuv_range()
) :: {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}

Converts the raw YUV data in a .yuv file into an RGB image.

The data is assumed, and required to be in:

  • Planar format
  • 8-bit color depth

Arguments

  • path is any accessible file system path.

  • width is the width of the image encoded in the YUV data.

  • height is the height of the image encoded in the YUV data.

  • encoding is one of :C444, :C422 or :C420.

  • colorspace is one of :bt601 (the default) or :bt709.

  • range is one of :limited (the default) or :full. See Image.YUV.yuv_range/0. It must match the range used when the data was encoded.

Returns

  • {:ok, rgb_image} or

  • {:error, reason}.

Examples

iex> image = Image.new!(8, 8, color: :green)
iex> path = Path.join(System.tmp_dir!(), "yuv_new_from_file_doctest.yuv")
iex> :ok = Image.YUV.write_to_file(image, path, :C420)
iex> {:ok, rgb_image} = Image.YUV.new_from_file(path, 8, 8, :C420)
iex> File.rm(path)
:ok
iex> Image.shape(rgb_image)
{8, 8, 3}

to_rgb(image, colorspace, range \\ :limited)

(since 0.41.0)
@spec to_rgb(
  image :: Vix.Vips.Image.t(),
  colorspace :: yuv_colorspace(),
  range :: yuv_range()
) ::
  {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}

Convert an image in an YUV colorspace and convert it to RGB colorspace.

Arguments

Examples

iex> yuv_image = Image.new!(8, 8, color: [128, 128, 128])
iex> {:ok, rgb_image} = Image.YUV.to_rgb(yuv_image, :bt601)
iex> {Image.shape(rgb_image), Image.colorspace(rgb_image)}
{{8, 8, 3}, :srgb}

to_rgb(yuv, width, height, encoding, colorspace \\ :bt601, range \\ :limited)

(since 0.41.0)
@spec to_rgb(
  yuv :: yuv_list(),
  width :: pos_integer(),
  height :: pos_integer(),
  encoding :: yuv_encoding(),
  colorspace :: yuv_colorspace(),
  range :: yuv_range()
) :: {:ok, Vix.Vips.Image.t()} | {:error, Image.error()}

Takes the [y, u, v] planes and converts them to an RGB image.

Arguments

  • yuv is a list of three binaries representing the Y, U and V planes. Such a list is returned from Image.YUV.to_yuv/3 and from Image.YUV.encode/2.

  • width is the width of the image encoded in yuv.

  • height is the height of the image encoded in yuv.

  • encoding is one of :C444, :C422 or :C420 representing how yuv is encoded.

  • colorspace is one of :bt601 (the default) or :bt709 that represents the colorspace of image before conversion.

  • range is one of :limited (the default) or :full. See Image.YUV.yuv_range/0.

Returns

  • {:ok, image} or

  • {:error, reason}.

Examples

iex> y = :binary.copy(<<235>>, 64)
iex> u = :binary.copy(<<128>>, 64)
iex> v = :binary.copy(<<128>>, 64)
iex> {:ok, image} = Image.YUV.to_rgb([y, u, v], 8, 8, :C444, :bt601)
iex> Image.shape(image)
{8, 8, 3}

to_yuv(image, encoding, colorspace \\ :bt601, range \\ :limited)

(since 0.41.0)
@spec to_yuv(
  image :: Vix.Vips.Image.t(),
  encoding :: yuv_encoding(),
  colorspace :: yuv_colorspace(),
  range :: yuv_range()
) :: {:ok, yuv_list()} | {:error, Image.error()}

Converts an image to raw YUV data as a binary.

Arguments

  • image is any t:Vimage.t/0.

  • encoding is one of :C444, :C422 or :C420.

  • colorspace is one of :bt601 (the default) or :bt709.

  • range is one of :limited (the default) or :full. See Image.YUV.yuv_range/0.

Returns

  • {:ok, [y, u, v]} or

  • {:error, reason}.

Examples

iex> image = Image.new!(8, 8, color: :red)
iex> {:ok, [y, u, v]} = Image.YUV.to_yuv(image, :C420)
iex> {byte_size(y), byte_size(u), byte_size(v)}
{64, 16, 16}

valid_colorspaces()

@spec valid_colorspaces() :: [:bt601 | :bt709]

Returns the list of YUV → RGB conversion colorspaces supported by this module.

Examples

iex> Image.YUV.valid_colorspaces()
[:bt601, :bt709]

valid_encodings()

@spec valid_encodings() :: [:C444 | :C422 | :C420]

Returns the list of YUV chroma-subsampling encodings supported by this module.

Examples

iex> Image.YUV.valid_encodings()
[:C444, :C422, :C420]

valid_ranges()

@spec valid_ranges() :: [:limited | :full]

Returns the list of YUV signal ranges supported by this module.

See Image.YUV.yuv_range/0 for the meaning of each range.

Examples

iex> Image.YUV.valid_ranges()
[:limited, :full]

write_to_binary(image, encoding, colorspace \\ :bt601, range \\ :limited)

(since 0.41.0)
@spec write_to_binary(
  image :: Vix.Vips.Image.t(),
  encoding :: yuv_encoding(),
  colorspace :: yuv_colorspace(),
  range :: yuv_range()
) :: {:ok, binary()} | {:error, Image.error()}

Writes an image to a YUV raw binary.

Arguments

  • image is any t:Vimage.t/0.

  • encoding is one of :C444, :C422 or :C420.

  • colorspace is one of :bt601 (the default) or :bt709.

  • range is one of :limited (the default) or :full. See Image.YUV.yuv_range/0.

Returns

  • {:ok, yuv_binary} or

  • {:error, reason}.

Examples

iex> image = Image.new!(8, 8, color: :green)
iex> {:ok, binary} = Image.YUV.write_to_binary(image, :C420)
iex> byte_size(binary)
96

write_to_file(image, path, encoding, colorspace \\ :bt601, range \\ :limited)

(since 0.41.0)
@spec write_to_file(
  image :: Vix.Vips.Image.t(),
  path :: Path.t(),
  encoding :: yuv_encoding(),
  colorspace :: yuv_colorspace(),
  range :: yuv_range()
) :: :ok | {:error, Image.error()}

Writes an image to a YUV file as raw YUV data.

It is recommeneded, but not required, that the path name use a .yuv suffix.

Arguments

  • path is any accessible file system path.

  • encoding is one of :C444, :C422 or :C420.

  • colorspace is one of :bt601 (the default) or :bt709.

  • range is one of :limited (the default) or :full. See Image.YUV.yuv_range/0.

Returns

  • :ok or

  • {:error, reason}.

Examples

iex> image = Image.new!(8, 8, color: :green)
iex> path = Path.join(System.tmp_dir!(), "yuv_write_to_file_doctest.yuv")
iex> Image.YUV.write_to_file(image, path, :C420)
:ok
iex> File.rm(path)
:ok