diff options
author | gennyble <gen@nyble.dev> | 2024-01-16 16:41:12 -0600 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2024-01-16 16:41:12 -0600 |
commit | 0ea17ff4a961b9a28a1d1263e6dc792aa3ae3f34 (patch) | |
tree | 4f6bf1d6bf3d6aa90b97afafa0a28a49c681ffb5 | |
parent | 9c58d09402d57ef8bf03c98c3d8dac88da4aebea (diff) | |
download | colorsquash-0ea17ff4a961b9a28a1d1263e6dc792aa3ae3f34.tar.gz colorsquash-0ea17ff4a961b9a28a1d1263e6dc792aa3ae3f34.zip |
squash: allow selecting scale and print verbose
-rw-r--r-- | squash/src/cli.rs | 27 | ||||
-rw-r--r-- | squash/src/main.rs | 31 |
2 files changed, 55 insertions, 3 deletions
diff --git a/squash/src/cli.rs b/squash/src/cli.rs index ba1658a..e33015e 100644 --- a/squash/src/cli.rs +++ b/squash/src/cli.rs @@ -10,12 +10,14 @@ const AUTHORS: &str = env!("CARGO_PKG_AUTHORS"); pub struct Cli { pub color_count: u8, pub tolerance: Option<f32>, + pub scale: u8, pub selector: Selector, pub difference: &'static DiffFn, pub input: Utf8PathBuf, pub in_type: InType, pub output: Utf8PathBuf, pub out_type: OutType, + pub verbose: bool, } // It's not a builder, but I think the builder/building name is useful @@ -24,8 +26,10 @@ pub struct Cli { struct BuildingCli { pub color_count: Option<u8>, pub tolerance: Option<f32>, + pub scale: Option<u8>, pub difference: DifferenceFn, pub selector: Selector, + pub verbose: bool, } impl BuildingCli { @@ -70,11 +74,13 @@ impl BuildingCli { color_count: self.color_count.unwrap_or(Self::DEFAULT_COLORS), tolerance: self.tolerance, selector: self.selector, + scale: self.scale.unwrap_or(25), difference, input, in_type, output, out_type, + verbose: self.verbose, } } } @@ -150,6 +156,19 @@ pub fn build() -> Cli { building.tolerance = Some(tol); } }, + Some(("scale", scale)) => match scale.parse::<u8>() { + Err(_) => { + eprintln!("scale must be >= 1 and <= 100"); + std::process::exit(1); + } + Ok(scale) if scale < 1 || scale > 100 => { + eprintln!("scale must be >= 1 and <= 100"); + std::process::exit(1); + } + Ok(scale) => { + building.scale = Some(scale); + } + }, Some(("difference", algo)) | Some(("dif", algo)) => match algo { "rgb" => building.difference = DifferenceFn::Rgb, "redmean" => building.difference = DifferenceFn::Redmean, @@ -166,6 +185,9 @@ pub fn build() -> Cli { std::process::exit(1); } }, + Some(("loud", _)) | Some(("verbose", _)) => { + building.verbose = true; + } Some(("help", "algorithms")) => print_help_algorithms(), Some(("help", "selectors")) => print_help_selectors(), Some(("help", _)) => print_help(), @@ -199,6 +221,9 @@ fn print_help() -> ! { println!(" the number of colours the final image should contain"); println!(" a whole number more than 0 and less than, or equal, 256"); println!(" [Default 256]\n"); + println!(" scale=<int>"); + println!(" the percent of pixels to consider when selecting the palette"); + println!(" for the image. Whole number 1 to 100, inclusive. [Default 25]\n"); println!(" difference=<algorithm> | dif=<algorithm>"); println!(" the color comparison function to use. one of: rgb, redmean"); println!(" for more details use help=algorithms. [Default rgb]\n"); @@ -209,6 +234,8 @@ fn print_help() -> ! { println!(" how different colours should be to be added to the palette"); println!(" only sort/select usese this value."); println!(" a number > 0 and <= 100 [Default 3]\n"); + println!(" loud= | verbose="); + println!(" print information about the image and palette.\n"); println!(" help= | -h | --help"); println!(" print this message and exit\n"); println!(" version= | -V | --version"); diff --git a/squash/src/main.rs b/squash/src/main.rs index 24d557f..c0cea51 100644 --- a/squash/src/main.rs +++ b/squash/src/main.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use colorsquash::{ selection::{Kmeans, SortSelect}, SquasherBuilder, @@ -34,11 +36,24 @@ fn main() -> Result<(), anyhow::Error> { cli::Selector::Kmeans => builder = builder.selector(Kmeans { max_iter: 10 }), }; - let start = std::time::Instant::now(); - let mut squasher = builder.build(&image.data); - println!("{:.2}ms", start.elapsed().as_secs_f32()); + let mut start = std::time::Instant::now(); + let mut squasher = builder.scale(cli.scale).build(&image.data); + + if cli.verbose { + println!( + "Palette is {} colors.\nSelection took {}", + squasher.palette().len(), + human_time(start.elapsed()) + ); + } + start = std::time::Instant::now(); let size = squasher.map_over(&mut image.data); + + if cli.verbose { + println!("Mapping took {}", human_time(start.elapsed())); + } + image.data.resize(size, 0); match cli.out_type { @@ -46,3 +61,13 @@ fn main() -> Result<(), anyhow::Error> { OutType::Gif => image::save_gif(image, squasher, cli.output), } } + +fn human_time(duration: Duration) -> String { + if duration.as_secs() > 0 { + format!("{:.2}s", duration.as_secs_f32()) + } else if duration.as_millis() >= 10 { + format!("{}ms", duration.as_millis()) + } else { + format!("{}μs", duration.as_micros()) + } +} |