#image-processing #color-space #key-value #image-encoding #container #metadata #imaging

refimage

Imaging library. Provides basic image processing and encoders/decoders for common image formats.

7 releases (4 breaking)

0.11.0 Sep 26, 2024
0.8.2 Sep 22, 2024

#141 in Images

Download history 203/week @ 2024-08-16 177/week @ 2024-08-23 4/week @ 2024-08-30 174/week @ 2024-09-06 345/week @ 2024-09-13 1060/week @ 2024-09-20 283/week @ 2024-09-27

1,862 downloads per month
Used in 2 crates

MIT/Apache

260KB
5.5K SLoC

refimage

crates.io Documentation

A Serializable Image Container

This crate provides a type-erased image container (GenericImageRef), backed by a contiguous slice (owned or referenced) of primitive (u8, u16, f32) pixels, with arbitrary color space (grayscale, Bayer pattern, RGB, ...) and color channels support (max. 255). Image sizes are limited to 65536 × 65536 for practical reasons.

GenericImageRef and GenericImageOwned are powerful, since these metadata in the form of (key, value) pairs, with optional comments. Valid metadata keys are case-insensitive, 80-character strings, and values are up to 64-bit integer types, 32- and 64-bit floating point numbers, strings up-to 4096 characters, or std::time::{SystemTime, Duration}.

GenericImageRef supports serialization, and, optionally can be saved in the open Flexible Image Transport System (FITS) through the FitsWrite trait, exposed through the fitsio optional feature. FITS files support lossless compression, and saving of arbitrary metadata.

GenericImageRef serializes to an internal representation which allows deserialization to GenericImageOwned. GenericImageOwned contains owned data, and is freely serialized-deserialized.

The path to a GenericImageRef

A GenericImageRef is obtained from a ImageRef object, created with the appropriate, contiguous, backing storage and image format:

use refimage::{BayerPattern, ImageRef, Debayer, DemosaicMethod, DynamicImageRef, GenericImageRef, GenericImageOwned};
use std::time::SystemTime;

let mut data = vec![0u8; 256]; // this is the backing store
// acquire(&mut data); // this function populates the backing store with the image pixels
let img = ImageRef::new(&mut data, 16, 16, BayerPattern::Grbg.into()).unwrap(); // Create a 4x4 image backed by the vector
let img = DynamicImageRef::from(img); // convert the `ImageRef` object to `DynamicImageRef`
let img = img.debayer(DemosaicMethod::Nearest).expect("Could not debayer"); // debayer the image using nearest neighbor method
let mut img = GenericImageOwned::new(SystemTime::now(), img); // Convert to a GenericImageRef
// insert the camera information as metadata
img.insert_key("CAMERA", ("Rust Test Program", "Name of the camera used to capture the image"));
let json = serde_json::to_string(&img).unwrap(); // serialize the image to JSON
let rimg: GenericImageOwned = serde_json::from_str(&json).unwrap(); // deserialize to GenericImageOwned
assert_eq!(&img, &rimg); // Confirm that deserialized image matches the original

The intention behind *ImageRef is to minimize unnecessary allocations.

GenericImageOwned and other ImageOwned types

An image can be loaded using the image crate from disk, by enabling the image feature:

use refimage::DynamicImageOwned;
use image::open;

let img = open("/path/to/image.png").expect("Could not load image");
let img = DynamicImageOwned::try_from(img).expect("Could not convert image");

Loading and storing a GenericImageRef

A GenericImageRef is intended to be loaded and stored in a standard format, e.g. bincode - which follows trivially from the serialization of GenericImageRef. However, for more portable applications, with the fitsio feature, a GenericImageRef can be stored as a FITS file by importing the FitsWrite trait. The FITS file is stored using the fitsio crate, which is a thin wrapper around the cfitsio library.

use refimage::{FitsCompression, FitsWrite, GenericImageRef}; // we need the FitsWrite trait to be able to use the `write_fits` method.
use std::path::Path;
let img: GenericImageRef = { todo!() }; // obtain a GenericImageRef
img.write_fits(Path::new("/path/to/fitsimage.fit"), FitsCompression::None, true) // no compression, overwrite
    .expect("Could not write FITS file.");

Additional Features

ToLuma and AlphaChannel traits are implemented on all image functions. The methods in these traits succeed only when allocation is required, and return a corresponding *ImageOwned object.

Optional Features

Features are available to extend the functionalities of the core refimage data types:

  • rayon: Parallelizes to_luma, to_luma_custom, to_u8 and debayer functions (enabled by default).
  • serde_flate: Compresses the data using deflate during serialization (enabled by default).
  • fitsio: Exposes FitsWrite trait to write GenericImageRef and GenericImageOwned (disabled by default).
  • image: Enables TryFrom conversions between image::DynamicImage and refimage::DynamicImageRef, refimage::DynamicImageOwned (disabled by default).

Dependencies

~3–6.5MB
~105K SLoC