Crate rscolorq[−][src]
A library and command line tool for spatial color quantization.
Overview
Rust port of Derrick Coetzee’s scolorq
, based on the 1998 paper
“On spatial quantization of color images” by Jan Puzicha, Markus Held, Jens
Ketterer, Joachim M. Buhmann, & Dieter Fellner. Spatial quantization is
defined as simultaneously performing halftoning (dithering) and color
quantization (limiting the colors in an image). For more information, visit
the original implementation’s website.
The algorithm is excellent for retaining image detail and minimizing visual distortions for color palettes in the neighborhood of 4, 8, or 16 colors, especially as the image size is reduced. It combines limiting the color palette and dithering the image into a simultaneous process as opposed to sequentially limiting the colors then dithering. Colors are chosen based on their context in the image, hence the “spatial” aspect of spatial color quantization. The colors are selected based on their neighbors to mix as an average illusory color in the human eye.
To use as a library, add the following to your Cargo.toml
; add the
palette_color
feature to enable Lab color quantization. See the
README.md for image examples, output, and usage.
[dependencies.rscolorq]
version = "0.1"
default-features = false
Usage
The following example shows the mapping of an image buffer in Rgb from
[u8; 3]
to [f64; 3]
, performing the color quantization, then filling
a buffer with u8
to be saved as an image.
use rscolorq::{color::Rgb, spatial_color_quant, Matrix2d, Params}; // Create the output buffer and quantized palette index buffer let mut imgbuf = Vec::with_capacity(width * height * 3); let mut quantized_image = Matrix2d::new(width, height); // Build the quantization parameters, verify if accepting user input let mut conditions = Params::new(); conditions.palette_size(palette_size); conditions.verify_parameters()?; // Convert the input image buffer from Rgb<u8> to Rgb<f64> let image = Matrix2d::from_vec( img.iter() .map(|&c| Rgb { red: c[0] as f64 / 255.0, green: c[1] as f64 / 255.0, blue: c[2] as f64 / 255.0, }) .collect(), width, height, ); let mut palette = Vec::with_capacity(palette_size as usize); spatial_color_quant(&image, &mut quantized_image, &mut palette, &conditions)?; // Convert the Rgb<f64> palette to Rgb<u8> let palette = palette .iter() .map(|&c| { let color = 255.0 * c; [ color.red.round() as u8, color.green.round() as u8, color.blue.round() as u8, ] }) .collect::<Vec<[u8; 3]>>(); // Create the final image by color lookup from the palette for &c in quantized_image.iter() { let color = palette .get(c as usize) .ok_or("Could not retrieve color from palette")?; imgbuf.extend_from_slice(color); }
Features
- use RGB or Lab color space for calculations
- can dither based on fixed color palette
- seedable RNG for reproducible results
Limitations
It’s “slow”
- Larger images or images with smooth transitions/gradients will take longer. Higher palette sizes will take longer.
- The algorithm is suited towards retaining detail with smaller color palettes. You can still use it on larger images but be aware it’s not close to real-time unless the image is small.
Filter size 1x1
- Doesn’t produce an image resembling the input, nor does the original.
Filter size 5x5
- Doesn’t always converge.
- I’m unsure if this is an error in this implementation or a problem with the random number generator being used. The original implementation may take a while but eventually completes with filter size 5.
- Any help on this would be appreciated.
Modules
color | Colors that can be used for spatial color quantization. |
Structs
Matrix2d | Two-dimensional matrix. |
Matrix3d | Three-dimensional matrix. |
Params | Input parameter struct for spatial color quantization and simulated
annealing. The parameters can be validated with
|
Enums
FilterSize | Square filter size for the quantization. |
QuantError | Indicates that an error has occurred in the quantization calculation. |
Traits
MatrixComponent | A trait for calculating the inverse of a matrix. |
SpatialQuant | A trait required to calculate the spatial quantization on a color type. |
Functions
spatial_color_quant | Perform the spatial color quantization. The mutated input parameters are a 2-dimensional matrix with the quantized color palette indices and the quantized color palette. |