This commit is contained in:
mehbark 2024-12-10 13:53:32 -05:00
commit 6d22aa0065
3 changed files with 1105 additions and 0 deletions

1024
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

9
Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "black-and-white-rainbows"
version = "0.1.0"
edition = "2021"
[dependencies]
hsl = "0.1.1"
image = "0.25.5"
itertools = "0.13.0"

72
src/main.rs Normal file
View file

@ -0,0 +1,72 @@
use std::{collections::HashMap, env};
use hsl::HSL;
use image::{GenericImage, GenericImageView, Pixel, Rgb, Rgba};
use itertools::Itertools;
#[allow(clippy::many_single_char_names)]
fn main() {
let mut args = env::args().skip(1);
let in_path = args.next().expect("i need a PATH. now!");
let start_x = args
.next()
.and_then(|n| n.parse::<i32>().ok())
.expect("start x");
let start_y = args
.next()
.and_then(|n| n.parse::<i32>().ok())
.expect("start y");
let out_path = args.next().expect("out path");
let mut img = image::open(in_path).expect("i wanna open an image");
// let's just hsl-rotate floodfill first
let mut covered = HashMap::new();
covered.insert((start_x, start_y), HSL::from_rgb(&[255, 0, 0]));
// TODO: hold front and covered. duh
// scale based on longest path (ez)
loop {
let mut front = HashMap::new();
for ((x, y), hsl) in &covered {
for (dx, dy) in (-1..=1).cartesian_product(-1..=1) {
let (x, y) = (x + dx, y + dy);
let Ok(x_idx) = x.try_into() else {
break;
};
let Ok(y_idx) = y.try_into() else {
break;
};
if img.in_bounds(x_idx, y_idx)
&& !is_dark(img.get_pixel(x_idx, y_idx).to_rgb())
&& !covered.contains_key(&(x, y))
{
let mut color = *hsl;
color.h += 1.;
if color.h >= 360. {
color.h = 0.;
}
let (r, g, b) = color.to_rgb();
img.put_pixel(x_idx, y_idx, Rgba([r, g, b, 255]));
front.insert((x, y), color);
}
}
}
if front.is_empty() {
break;
}
covered.extend(front);
}
img.save(out_path).expect("tried to save :(");
}
fn is_dark(pixel: Rgb<u8>) -> bool {
let Rgb([r, g, b]) = pixel;
r < 127 && g < 127 && b < 127
}