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
use super::*;
use optimizer::Optimizer;
use ditherer::Ditherer;
pub fn convert_to_indexed<D, O>(image: &[Color],
width: usize,
num_colors: usize,
optimizer: &O,
ditherer: &D)
-> (Vec<Color>, Vec<u8>)
where D: Ditherer,
O: Optimizer
{
let colorspace = SimpleColorSpace::default();
let hist = image.iter().cloned().collect();
let palette = generate_palette(&hist, &colorspace, optimizer, num_colors);
let palette = optimizer.optimize_palette(&colorspace, &palette, &hist, 8);
let image = Remapper::new(&palette, &colorspace, ditherer).remap(image, width);
sort_palette(&palette, &image)
}
pub fn generate_palette<C, O>(hist: &Histogram,
colorspace: &C,
optimizer: &O,
num_colors: usize)
-> Vec<Color>
where C: ColorSpace,
O: Optimizer
{
let mut quantizer = Quantizer::new(hist, colorspace);
let kmeans_step = if num_colors > 64 {
num_colors
} else if num_colors <= 16 {
1
} else {
(num_colors as f64).sqrt().round() as usize
};
while quantizer.num_colors() < num_colors {
quantizer.step();
if quantizer.num_colors() % kmeans_step == 0 {
quantizer = quantizer.optimize(optimizer, 4);
}
}
quantizer.colors(colorspace)
}