88 lines
2.6 KiB
Rust
88 lines
2.6 KiB
Rust
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<String> = 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<u8>) -> 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);
|
|
}
|
|
}
|