diff options
author | gennyble <gen@nyble.dev> | 2024-01-16 15:54:02 -0600 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2024-01-16 15:54:06 -0600 |
commit | 9c58d09402d57ef8bf03c98c3d8dac88da4aebea (patch) | |
tree | 91443f51bbc20a4ea6e557b73a3260734c718ff6 /src/lib.rs | |
parent | c887f5fef803e720052898b9561028dfd50e51db (diff) | |
download | colorsquash-9c58d09402d57ef8bf03c98c3d8dac88da4aebea.tar.gz colorsquash-9c58d09402d57ef8bf03c98c3d8dac88da4aebea.zip |
colorsquash: scale image for palette selection for massive speedup
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 40 |
1 files 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<T: Count> { + scale: u8, max_colours: T, difference_fn: Box<DiffFn>, selector: Option<Box<dyn Selector + 'static>>, @@ -23,6 +24,7 @@ impl<T: Count> SquasherBuilder<T> { pub fn new() -> Self { Self { max_colours: T::zero(), + scale: 100, difference_fn: Box::new(difference::rgb), selector: None, } @@ -36,6 +38,13 @@ impl<T: Count> SquasherBuilder<T> { 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<T: Count> SquasherBuilder<T> { where Img: Into<ImageData<'a>>, { - 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<T> { max_colours_min1: T, palette: Vec<RGB8>, map: Vec<T>, + scale: u8, selector: Box<dyn Selector + 'static>, difference_fn: Box<DiffFn>, } @@ -84,6 +98,7 @@ impl<T: Count> Squasher<T> { Img: Into<ImageData<'a>>, { let mut this = Self::from_parts( + 100, max_colors_minus_one, Box::new(difference::rgb), Box::new(selector), @@ -102,13 +117,31 @@ impl<T: Count> Squasher<T> { where Img: Into<ImageData<'a>>, { + 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<DiffFn>, selector: Box<dyn Selector>, @@ -117,6 +150,7 @@ impl<T: Count> Squasher<T> { max_colours_min1, palette: vec![], map: vec![T::zero(); 256 * 256 * 256], + scale, difference_fn, selector, } |