From 9c58d09402d57ef8bf03c98c3d8dac88da4aebea Mon Sep 17 00:00:00 2001 From: gennyble Date: Tue, 16 Jan 2024 15:54:02 -0600 Subject: colorsquash: scale image for palette selection for massive speedup --- src/lib.rs | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cbecf76..83dc55e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ use difference::DiffFn; use selection::Selector; pub struct SquasherBuilder { + scale: u8, max_colours: T, difference_fn: Box, selector: Option>, @@ -23,6 +24,7 @@ impl SquasherBuilder { pub fn new() -> Self { Self { max_colours: T::zero(), + scale: 100, difference_fn: Box::new(difference::rgb), selector: None, } @@ -36,6 +38,13 @@ impl SquasherBuilder { self } + /// The percent of pixels to consider while selecting the palette for the + /// image. Integer between 1 and 100 (inclusive) + pub fn scale(mut self, scale: u8) -> Self { + self.scale = scale; + self + } + /// The function to use to compare colours while mapping the image. /// /// see the [difference] module for functions included with the crate and @@ -54,8 +63,12 @@ impl SquasherBuilder { where Img: Into>, { - let mut squasher = - Squasher::from_parts(self.max_colours, self.difference_fn, self.selector.unwrap()); + let mut squasher = Squasher::from_parts( + self.scale, + self.max_colours, + self.difference_fn, + self.selector.unwrap(), + ); squasher.recolor(image); squasher @@ -67,6 +80,7 @@ pub struct Squasher { max_colours_min1: T, palette: Vec, map: Vec, + scale: u8, selector: Box, difference_fn: Box, } @@ -84,6 +98,7 @@ impl Squasher { Img: Into>, { let mut this = Self::from_parts( + 100, max_colors_minus_one, Box::new(difference::rgb), Box::new(selector), @@ -102,13 +117,31 @@ impl Squasher { where Img: Into>, { + let data = image.into(); + + let nth = 100 / self.scale as usize; + let count = data.0.len() / nth; + let mut scaled = vec![RGB8::default(); count]; + #[allow(clippy::needless_range_loop)] // sorry clippy, i like it + for idx in 0..count { + scaled[idx] = data.0[idx * nth]; + } + self.palette = self .selector - .select(self.max_colours_min1.as_usize() + 1, image.into()); + .select(self.max_colours_min1.as_usize() + 1, ImageData(&scaled)); + } + + /// A number between 1 and 100 (inclusive) for how many pixels of the image + /// to consider when selecting the palette. + pub fn set_scale(&mut self, scale: u8) { + assert!(scale > 0 && scale <= 100); + self.scale = scale; } /// Create a Squasher from parts. Noteably, this leave your palette empty fn from_parts( + scale: u8, max_colours_min1: T, difference_fn: Box, selector: Box, @@ -117,6 +150,7 @@ impl Squasher { max_colours_min1, palette: vec![], map: vec![T::zero(); 256 * 256 * 256], + scale, difference_fn, selector, } -- cgit 1.4.1-3-g733a5