use image::{DynamicImage, GenericImageView, Pixel, Rgb, RgbImage, ImageBuffer}; use std::env; mod xkcd_colours; mod x11_colours; mod css_colours; //use xkcd_colours as colours; //use x11_colours as colours; use css_colours as colours; fn main() { let args: Vec = env::args().collect(); if args.len() == 2 { process_image_file(&args[1]); } replace_colours_with_nearest(); } fn replace_colours_with_nearest() { let img = image::open("resources/pexels-scott-webb-137594.jpg").unwrap(); let (width, height) = img.dimensions(); let mut out: RgbImage = ImageBuffer::new(width, height); for x in 0..width { for y in 0..height { let pixel = img.get_pixel(x, y).to_rgb(); out.put_pixel(x, y, Rgb(get_nearest_colour(pixel).to_rgb())); } } out.save("out.jpg").unwrap(); } fn get_all_nearest_colours(img: DynamicImage) -> Vec<(colours::Colour, u32)> { let mut colours: Vec<(colours::Colour, u32)> = Vec::with_capacity(colours::NUM_COLOURS); for c in colours::Colour::iterator() { colours.push((c.clone(), 0)); } for pixel in img.pixels() { let pixel_colour = get_nearest_colour(pixel.2.to_rgb()); colours[pixel_colour as usize].1 = colours[pixel_colour as usize].1 + 1; } colours.retain(|(_c, n)| *n != 0 as u32); colours.sort_by(|a, b| b.1.cmp(&a.1)); colours } fn get_nearest_colour(p: Rgb) -> colours::Colour { let mut lowest_distance = f64::MAX; let mut closest_colour = colours::Colour::Black; for col in colours::Colour::iterator() { let c = col.to_rgb(); let d = (p.0[0] as i32 - c[0] as i32).pow(2) + (p.0[1] as i32 - c[1] as i32).pow(2) as i32 + (p.0[2] as i32 - c[2] as i32).pow(2); let d = (d as f64).sqrt(); if d < lowest_distance { closest_colour = col.clone(); lowest_distance = d; } } closest_colour } fn process_image_file(file: &str) -> Vec<(colours::Colour, u32)> { let img = image::open(file).unwrap(); let colours = get_all_nearest_colours(img); colours } #[cfg(test)] mod tests { use super::*; #[test] fn test_rusty_pic() { let colours = process_image_file("resources/pexels-scott-webb-137594.jpg"); println!("{:?}", colours); } #[test] fn test_birdy_pic() { let colours = process_image_file("resources/pexels-erik-karits-3761421.jpg"); println!("{:?}", colours); } #[test] fn test_painty_pic() { let colours = process_image_file("resources/pexels-steve-johnson-1070536.jpg"); println!("{:?}", colours); } }