@@ -3,11 +3,14 @@ use anyhow::Result;
3
3
use clap:: Parser ;
4
4
use image:: {
5
5
imageops:: { resize, FilterType } ,
6
- ImageBuffer , Pixel , Rgb , Rgba ,
6
+ ImageBuffer , Rgb , Rgba ,
7
7
} ;
8
8
use kmeans_colors:: get_kmeans;
9
9
use palette:: { cast:: ComponentsAs , FromColor , Srgb , Srgba } ;
10
- use rayon:: iter:: { ParallelIterator , IntoParallelRefIterator } ;
10
+ use rayon:: {
11
+ iter:: { IntoParallelRefIterator , ParallelIterator } ,
12
+ } ;
13
+ use rayon:: slice:: ParallelSliceMut ;
11
14
use tracing:: info;
12
15
use tracing_subscriber:: FmtSubscriber ;
13
16
@@ -123,14 +126,25 @@ fn find_palette(image: &Image, num_colors: usize, transparent: bool) -> Result<V
123
126
///
124
127
/// If the palette is empty, all pixel colors will become black (`Rgb([0, 0, 0])`).
125
128
fn reduce_colors ( image : & mut Image , palette : & [ Rgb < u8 > ] ) {
126
- image. enumerate_pixels_mut ( ) . for_each ( |( _, _, pixel) | {
129
+ // Obtain a mutable reference to the underlying raw pixel buffer. Each pixel consists of 4 u8 channels (RGBA)
130
+ let raw_pixels = image. as_mut ( ) ;
131
+
132
+ raw_pixels. par_chunks_mut ( 4 ) . for_each ( |p| {
133
+ // Interpret the first three bytes as the RGB values.
134
+ let pixel_rgb = Rgb ( [ p[ 0 ] , p[ 1 ] , p[ 2 ] ] ) ;
135
+
136
+ // Iterate sequentially over the small palette to compute the closest color.
127
137
let closest_color = palette
128
- . par_iter ( )
138
+ . iter ( )
139
+ . min_by_key ( |& color| compute_squared_distance ( & pixel_rgb, color) )
129
140
. copied ( )
130
- . min_by_key ( |& color| compute_squared_distance ( & color, & pixel. to_rgb ( ) ) )
131
141
. unwrap_or ( Rgb ( [ 0 , 0 , 0 ] ) ) ;
132
142
133
- * pixel = Rgba ( [ closest_color[ 0 ] , closest_color[ 1 ] , closest_color[ 2 ] , pixel[ 3 ] ] ) ;
143
+ // Update the pixel with the closest color, leaving the alpha channel unchanged.
144
+ p[ 0 ] = closest_color[ 0 ] ;
145
+ p[ 1 ] = closest_color[ 1 ] ;
146
+ p[ 2 ] = closest_color[ 2 ] ;
147
+ // p[3] (alpha) remains unchanged
134
148
} ) ;
135
149
}
136
150
0 commit comments