#rgb #yuv

ezk-image

Convert pixel and color formats such and RGB, YUV (YCbCr), ICtCp

14 unstable releases (3 breaking)

Uses new Rust 2024

0.4.2 Nov 3, 2025
0.4.1 Nov 2, 2025
0.3.0 Sep 14, 2025
0.2.4 Nov 27, 2024
0.1.0 May 14, 2024

#129 in Images

Download history 242/week @ 2025-10-27 705/week @ 2025-11-03 273/week @ 2025-11-10 409/week @ 2025-11-17 342/week @ 2025-11-24 1115/week @ 2025-12-01 330/week @ 2025-12-08 117/week @ 2025-12-15 671/week @ 2025-12-22 208/week @ 2025-12-29 516/week @ 2026-01-05 758/week @ 2026-01-12 386/week @ 2026-01-19 1433/week @ 2026-01-26 440/week @ 2026-02-02 572/week @ 2026-02-09

2,945 downloads per month
Used in opentalk-compositor

MIT license

245KB
6.5K SLoC

EZK Image

ezk-image is a crate to perform conversion between common pixel formats and color spaces.

It uses SIMD and multi threading to accelerate the conversion when available, though multi-threading must be explicitly called with convert_multi_thread.

Any format can be converted to any other format.


Supported Pixel formats

Bit depth of up to 16 bit per component is supported.

  • I420
  • I422
  • I444
  • I010, I012
  • I210, I212
  • I410, I412
  • NV12
  • YUYV
  • RGBA, BGRA
  • RGB, BGR

Supported Color Primaries (color gamut)

  • SMTPE ST 240
  • BT.709 (SDR)
  • BT.2020 (HDR)

Supported Color Transfer Functions (opto-electronic transfer characteristics of samples)

  • Linear
  • Gamma of 2.2 and 2.8
  • SRGB
  • SDR (BT.601, BT.709 and BT.2020)
  • BT.2100 perceptual quantization (PQ)
  • BT.2100 hybrid log-gamma (HLG)

Supported Color Spaces

  • RGB
  • YUV BT.601
  • YUV BT.709
  • YUV BT.2020
  • ICtCp with perceptual quantization (PQ)
  • ICtCp with hybrid log-gamma (HLG)

Example

use ezk_image::*;

let (width, height) = (1920, 1080);

// Our source image, an RGB buffer
let rgb_image = vec![0u8; PixelFormat::RGB.buffer_size(width, height)];

// Create the image we're converting from
let source = Image::from_buffer(
    PixelFormat::RGB,
    &rgb_image[..], // RGB only has one plane
    None, // No need to define strides if there's no padding between rows
    width,
    height,
    ColorInfo::RGB(RgbColorInfo {
        transfer: ColorTransfer::Linear,
        primaries: ColorPrimaries::BT709,
    }),
).unwrap();

// Create the image buffer we're converting to
let mut destination = Image::blank(
    PixelFormat::NV12, // We're converting to NV12
    width,
    height,
    ColorInfo::YUV(YuvColorInfo {
        space: ColorSpace::BT709,
        transfer: ColorTransfer::Linear,
        primaries: ColorPrimaries::BT709,
        full_range: false,
    }),
);

// Now convert the image data
convert_multi_thread(
    &source,
    &mut destination,
).unwrap();

Dependencies

~0.2–1.1MB
~24K SLoC