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()
/// });
/// ```
/// 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