initial
This commit is contained in:
commit
6d22aa0065
3 changed files with 1105 additions and 0 deletions
1024
Cargo.lock
generated
Normal file
1024
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
9
Cargo.toml
Normal file
9
Cargo.toml
Normal 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
72
src/main.rs
Normal 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
|
||||||
|
}
|
Loading…
Reference in a new issue