This crate provides easy image 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.
There are three main struct types in this crate: views, flat buffers and buffers. A view is a read-only image representation, whereas a buffer is writable since it owns its backing memory. Finally, flat buffers are writable as well but take (mutable) existing memory regions to operate on.
This crate shall facilitate zero-allocation image buffer conversion through views flat buffers. Additionally, full buffers can be created when a new output buffer is needed or the existing buffer is to small.
There are two main APIs: packed
for traditional packed images and planar
for memory-to-memory (M2M) usecases. See Packed and Planar APIs for more information.
Two distinct APIs are planned: packed and planar. 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:
..|RGB|RGB|RGB|.. (single memory plane)
whereas a planar RGB image would look like this:
..|RRR|GGG|BBB|.. (three memory planes)
Below you can find a quick example usage of this crate. It introduces the basics necessary for image conversion.
```rust use ffimage::prelude::*;
fn main() { // This is our grayscale image memory. // Usually, this will be allocated by a foreign function (e.g. kernel driver) and contain // read-only memory. let mem: [u8; 12] = [0; 12];
// Create a statically typed view of the image, assuming it is RGB 24 bits per pixel.
// The u8 parameter denotes the internal storage type used by image pixels. In our case, each
// channel requires eight bits, which makes for a total of 3 * 8 = 24 bits per pixel.
// The length of the memory slice is validated and a None value is returned when constraints
// are violated.
let view = PackedImageView::<Rgb<u8>>::new(&mem, 2, 2).unwrap();
// Create a target buffer for the destination image.
// Here we initialize an empty buffer with width and height both being zero. This is fine since
// the `Convert` trait implementation will resize the target buffer for us.
let mut buf = PackedImageBuffer::<Gray<u8>>::new(0, 0);
// Perform the actual conversion.
// This cannot fail since the target buffer is resizable.
// If the pixel conversion between source and target image is not defined, the compiler will
// refuse to compile this line.
view.convert(&mut buf);
} ```
Have a look at the provided examples
for more sample applications.