Skip to main content

Crate imbuf

Crate imbuf 

Source
Expand description

CI

§This crate provides flexible image buffers

  • Allows transforming known Images (e.g. RGB32F) to typeless DynamicImages and back (without a single buffer copy)
  • Ability to support buffers from other libraries like “opencv” without copying buffers
  • Copy on write capability, so buffers can be reused if the internal representation allows it
  • FFI compatible

§Interleaved vs planar images

A 2x2 RGB image can either be interleaved (memory: rgbrgbrgbrgb) or planar(memory: rrrrggggbbbb) Interleaved RGB images are stored as Image<[u8;3], 1>, whereas planar images are stored as Image<u8, 3>. This crate provides utilities functions to go from one representation to the other.

§Channels

ImageChannel is a composeable building block for Image. If you have a special Image kind, where channels are not uniform, feel encouraged to add your own typed Image, which implement TryFrom<DynamicImage> and Into<DynamicImage>.

§Typed Images

The Image struct represents a fully typed Image to support the most common image formats.

TypeDescription
Image<u8, 3>RGB8 planar
Image<[u8; 4], 1>RGBA8 interleaved
Image<f32, 2>LUMAA32F planar
ImageRef<u8, 1>LUMA8, where buffers are borrowed
ImageMut<[u16;3], 1>RGB16 Interleaved, where buffers are mutually borrowed

§Example which demonstrates buffer reuse

use std::{num::NonZeroU32, sync::Arc};
use imbuf::{Image, DynamicImage, ImageChannel, DynamicImageChannel};

let pixel_data = vec![42, 1, 2];
let data_addr = pixel_data.as_ptr();
let image: Image<u8, 3> = imbuf::Image::new_vec(pixel_data, NonZeroU32::MIN, NonZeroU32::MIN);
let dynamic = DynamicImage::from(image);
let dynamic_clone = dynamic.clone();
{
    assert_eq!(1, dynamic.last().width().get(), "DynamicImage alwas contains >=1 channels");
    let untyped_channel = dynamic.into_iter().next().unwrap();
    let mut typed_channel = ImageChannel::<u8>::try_from(untyped_channel).unwrap();
    assert_eq!(42, typed_channel.buffer()[0], "Value of the first channel is 0");
    assert_eq!(data_addr, typed_channel.buffer().as_ptr(), "shared pointer reuses the buffer");
    assert_ne!(data_addr, typed_channel.make_mut().as_ptr(), "dynamic_clone prevents mut buffer reuse");
}
let mut typed: Image<u8, 3> = dynamic_clone.try_into()?;
let [r, g, b] = typed.make_mut();
r[0] = 0;
assert_eq!(data_addr, r.as_ptr(), "dynamic went out of scope, so buffer can be reused");
let expected = imbuf::Image::new_vec(vec![0, 1, 2], NonZeroU32::MIN, NonZeroU32::MIN);
assert_eq!(expected, typed, "images with different buffer can be compared");

Structs§

DynamicImage
Image with number of channels and their types and dimensions only known at runtime There are no guarantees that the types or dimensions of channels match. See ImageChannels for more information. The public interface is designed, so it can be extended to support images, which cannot be represented with Image (e.g. 1 Channel u8 and the other f32)
DynamicSize
Removes all compile time hints, of how many channels a pixel persists This is primarily used in DynamicImageChannel
ImageChannel
Represents a plane of a image. In a Planar RGB image, this could be the R, G, or B channel Interleaved RGB images have a single channel, which is a array of pixels (TP: [u8; 3])
ImageChannelVTable
VTable for ImageChannel and UnsafeImageChannel
ImageChannels
Represents a image, where all channels share the same width, height. You usually want to use its typedef versions Image, ImageRef, ImageMut instead.
IncompatibleImageError
UnsafeImageChannel
This is only relevant when implementing a custom storage T is usually a PixelTypePrimitive, but it is not enforced by the type system

Enums§

DynamicImageChannel

Traits§

BorrowableImageChannel
PixelType
PixelTypePrimitive

Type Aliases§

Image
ImageMut
ImageRef
LumaImageDeprecated
RgbImageInterleavedDeprecated
RgbImagePlanarDeprecated
RgbaImageInterleavedDeprecated
RgbaImagePlanarDeprecated