Compare commits
2 Commits
58e9e91348
...
68313eaba9
| Author | SHA1 | Date | |
|---|---|---|---|
| 68313eaba9 | |||
| cb92a56b20 |
1166
Cargo.lock
generated
Normal file
1166
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "imagepicker"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
dotenv = "0.15.0"
|
||||||
|
image = {version = "0.25.10", features = ["png"]}
|
||||||
|
log = "0.4.29"
|
||||||
|
pretty_env_logger = "0.5.0"
|
||||||
|
rand = "0.10.1"
|
||||||
67
src/main.rs
Normal file
67
src/main.rs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
use std::{collections::{HashMap, HashSet}, env, num::ParseIntError};
|
||||||
|
|
||||||
|
use dotenv::dotenv;
|
||||||
|
use image::{DynamicImage, ImageReader, Rgb};
|
||||||
|
|
||||||
|
type ColourSet = HashMap<u8, HashMap<u8, HashSet<u8>>>;
|
||||||
|
type Colour = Rgb<u8>;
|
||||||
|
|
||||||
|
pub fn decode_hex(s: &str) -> Result<Colour, ParseIntError> {
|
||||||
|
Ok(Rgb((0..s.len())
|
||||||
|
.step_by(2)
|
||||||
|
.map(|i| u8::from_str_radix(&s[i..i + 2], 16))
|
||||||
|
.collect())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_colours(img: DynamicImage) -> ColourSet {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn closest_colour(colour: Colour, all: &ColourSet) -> Option<Colour> {
|
||||||
|
// use redmean to calculate the distance between colours
|
||||||
|
// inevitably O(len(all))
|
||||||
|
let mut closest: Option<Colour> = None;
|
||||||
|
let mut dist: f32 = f32::MAX;
|
||||||
|
for (r, gbs) in all.iter() {
|
||||||
|
let r_bar = 0.5 * (r + colour[0]) as f32;
|
||||||
|
let delta_r = ((r + colour[0]) * (r + colour[0])) as f32;
|
||||||
|
for (g, bs) in gbs.iter() {
|
||||||
|
let delta_g = ((g + colour[1]) * (g + colour[1])) as f32;
|
||||||
|
for b in bs {
|
||||||
|
let delta_b = ((b + colour[2]) * (b + colour[2])) as f32;
|
||||||
|
|
||||||
|
let delta = (2.0 + r_bar/256.0) * delta_r + 4.0 * delta_g + (2.0 + (255.0 - r_bar)/256.0) * delta_b;
|
||||||
|
if delta < dist {
|
||||||
|
dist = delta;
|
||||||
|
closest = Some(Rgb([*r,*g,*b]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closest
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
dotenv().ok();
|
||||||
|
pretty_env_logger::init();
|
||||||
|
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
if args.len() > 1 {
|
||||||
|
let img_file = &args[1];
|
||||||
|
let img = ImageReader::open(img_file).unwrap().decode().unwrap(); // FIXME: unwraps
|
||||||
|
|
||||||
|
let all_cols = extract_colours(img);
|
||||||
|
let mut output_cols: HashMap<Colour, Colour> = HashMap::new();
|
||||||
|
|
||||||
|
for c_str in args {
|
||||||
|
// TODO: parse args
|
||||||
|
let c = decode_hex(&c_str).unwrap(); // FIXME: unwraps;
|
||||||
|
if let Some(col) = closest_colour(c, &all_cols) {
|
||||||
|
output_cols.insert(c, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user