2 unstable releases

0.10.0 Oct 28, 2023
0.9.0 Mar 6, 2021

#2 in #gray

Download history 44/week @ 2024-07-15 4/week @ 2024-07-22 99/week @ 2024-07-29 76/week @ 2024-08-05 39/week @ 2024-08-12 17/week @ 2024-08-19 40/week @ 2024-08-26 42/week @ 2024-09-02 50/week @ 2024-09-09 63/week @ 2024-09-16 41/week @ 2024-09-23 27/week @ 2024-09-30 15/week @ 2024-10-07 9/week @ 2024-10-14 37/week @ 2024-10-21 19/week @ 2024-10-28

81 downloads per month
Used in 3 crates

MIT license

28KB
586 lines

Foreign function image handling

license Build Status

This crate provides easy image pixel handling and conversion capabilities in Rust. It is designed to work with image buffers originating from foreign functions, which could be a C API or a camera driver which maps device buffers into userspace.

Pixels are represented as array wrapper types, e.g. [T; 3] would be the inner type for an Rgb pixel. The crate provides iterator extensions so you can easily convert between color formats, e.g. Yuv and Rgb.

Packed and Planar APIs

Packed images have their pixels reside beneath each other in memory while planar images require separate memory planes for pixel components.

For example, a packed RGB image would look like this in memory:

R1G1B1 .. RnGnnn (single memory plane)

whereas a planar YUV420p image would look like this:

Y1Y2 .. Yn | U1U2 .. Un | V1V2 .. Vn (three memory planes)

Usage

Below you can find a quick example usage of this crate. It introduces the basics necessary for image conversion.

use ffimage::color::{Gray, Rgb};
use ffimage::iter::{BytesExt, ColorConvertExt, PixelsExt};

fn main() {
    // This is our RGB image memory (2x2 pixels).
    // Usually, this will be allocated by a foreign function (e.g. kernel driver) and contain
    // read-only memory.
    let rgb = [10; 4 * 3];
    // We need an output buffer as well to host the converted grayscale pixels.
    let mut gray = [0; 4 * 1];

    // Convert from rgb to grayscale by mapping each pixel. The Pixels iterator extension creates
    // a typed pixel iterator from a bytestream. The ColorConvert extension knows how to convert
    // between pixel types and the Write extension finally writes the pixels back into a
    // bytestream.
    rgb.iter()
        .copied()
        .pixels::<Rgb<u8>>()
        .colorconvert::<Gray<u8>>()
        .bytes()
        .write(&mut gray);
}

Benchmark

A benchmark suite is included in this crate. Run it using

$ cargo bench

These are my results for ffimage v0.10.0 on a MacBook Pro 14" (M1 Pro):

In Out 640x480 1280x720
Rgb[u8] Bgr[u8] 18.028 µs 53.882 µs
Rgb[u8] Gray[u8] 381.48 µs 1.1442 ms
Yuv[u8] Rgb[u8] 165.32 µs 496.33 µs
Yuv422[u8] Rgb[u8] 1.2097 ms 3.6284 ms

Dependencies

~150KB