1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
//! NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
//! See "Kohonen neural networks for optimal colour quantization"
//! in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
//! for a discussion of the algorithm.
//! See also <https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/>
/* NeuQuant Neural-Net Quantization Algorithm
* ------------------------------------------
*
* Copyright (c) 1994 Anthony Dekker
*
* NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
* See "Kohonen neural networks for optimal colour quantization"
* in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
* for a discussion of the algorithm.
* See also https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/
*
* Any party obtaining a copy of these files from the author, directly or
* indirectly, is granted, free of charge, a full and unrestricted irrevocable,
* world-wide, paid up, royalty-free, nonexclusive right and license to deal
* in this software and documentation files (the "Software"), including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons who receive
* copies from any such party to do so, with the only requirement being
* that this copyright notice remain intact.
*
*
* Incorporated bugfixes and alpha channel handling from pngnq
* http://pngnq.sourceforge.net
*
*/
/// Neural network color quantizer
///
/// # Examples
/// ```
/// use image::imageops::colorops::{index_colors, ColorMap};
/// use image::math::nq::NeuQuant;
/// use image::{ImageBuffer, Rgba, RgbaImage};
///
/// // Create simple color image with RGBA pixels.
/// let (w, h) = (2, 2);
/// let red: Rgba<u8> = [255, 0, 0, 255].into();
/// let green: Rgba<u8> = [0, 255, 0, 255].into();
/// let blue: Rgba<u8> = [0, 0, 255, 255].into();
/// let white: Rgba<u8> = [255, 255, 255, 255].into();
/// let mut color_image = RgbaImage::new(w, h);
/// color_image.put_pixel(0, 0, red);
/// color_image.put_pixel(1, 0, green);
/// color_image.put_pixel(0, 1, blue);
/// color_image.put_pixel(1, 1, white);
///
/// // Create a `NeuQuant` colormap that will build an approximate color palette that best matches
/// // the original image.
/// // Note, the NeuQuant algorithm is only designed to work with 6-8 bit output, so `colors`
/// // should be a power of 2 in the range [64, 256].
/// let pixels = color_image.clone().into_raw();
/// let cmap = NeuQuant::new(1, 256, &pixels);
/// // Map the original image through the color map to create an indexed image stored in a
/// // `GrayImage`.
/// let palletized = index_colors(&color_image, &cmap);
/// // Map indexed image back `RgbaImage`. Note the NeuQuant algorithm creates an approximation of
/// // the original colors, so even in this simple example the output is not pixel equivalent to
/// // the original.
/// let mapped = ImageBuffer::from_fn(w, h, |x, y| -> Rgba<u8> {
/// let p = palletized.get_pixel(x, y);
/// cmap.lookup(p.0[0] as usize)
/// .expect("indexed color out-of-range")
/// .into()
/// });
/// ```
#[deprecated(note = "Use the `color_quant` crate instead")]
pub struct NeuQuant {
inner: color_quant::NeuQuant,
}
/// The implementation only calls the corresponding inner `color_quant` methods.
///
/// These exist purely to keep a type separate from [`color_quant::NeuQuant`] and the interface
/// stable for this major version. The type will be changed to a pure re-export in the next
/// version or might be removed.
///
/// [`color_quant::NeuQuant`]: https://docs.rs/color_quant/1.1.0/color_quant/struct.NeuQuant.html
#[allow(deprecated)]
#[allow(missing_docs)]
impl NeuQuant {
pub fn new(samplefac: i32, colors: usize, pixels: &[u8]) -> Self {
color_quant::NeuQuant::new(samplefac, colors, pixels).into()
}
pub fn init(&mut self, pixels: &[u8]) {
self.inner.init(pixels)
}
pub fn map_pixel(&self, pixel: &mut [u8]) {
self.inner.map_pixel(pixel)
}
pub fn index_of(&self, pixel: &[u8]) -> usize {
self.inner.index_of(pixel)
}
pub fn lookup(&self, idx: usize) -> Option<[u8; 4]> {
self.inner.lookup(idx)
}
}
#[allow(deprecated)]
impl From<color_quant::NeuQuant> for NeuQuant {
fn from(inner: color_quant::NeuQuant) -> Self {
NeuQuant { inner }
}
}
#[allow(deprecated)]
impl From<NeuQuant> for color_quant::NeuQuant {
fn from(this: NeuQuant) -> Self {
this.inner
}
}