image sequence

This commit is contained in:
mehbark 2025-03-11 16:59:25 -04:00
parent a71a1af3fb
commit 3da437c4ba

View file

@ -12,9 +12,7 @@ const TYPE_COLORS_SRC: &str = include_str!("type-colors.json");
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
fmt, fmt, process,
path::PathBuf,
process,
}; };
use clap::Parser; use clap::Parser;
@ -26,27 +24,33 @@ use rand::{
}; };
use serde::Deserialize; use serde::Deserialize;
// i'm putting my foot down
const OUTPUT_DIGITS: usize = 5;
fn main() { fn main() {
let Args { let Args {
width, width,
height, height,
output_file, output_prefix,
steps, steps,
} = Args::parse(); } = Args::parse();
let mut rng = rand::rng(); let mut rng = rand::rng();
let mut game = Game::new_random(width, height, &mut rng); let mut game = Game::new_random(width, height, &mut rng);
for _ in 0..steps { for i in 0..steps {
game.step(&mut rng); game.step(&mut rng);
let path = format!("{output_prefix}{i:0OUTPUT_DIGITS$}.png");
if let Err(e) = ImageBuffer::from(&game).save(path) {
eprintln!("error saving image: {e}");
process::exit(1);
}
} }
// TODO: refactor to error enum to avoid this // TODO: refactor to error enum to avoid this
// TODO: animation (at least fast image sequence) // TODO: animation (at least fast image sequence)
// TODO: don't constantly alloc buffers
// if we need more errors // if we need more errors
if let Err(e) = ImageBuffer::from(game).save(output_file) {
eprintln!("error saving image: {e}");
process::exit(1);
}
} }
lazy_static! { lazy_static! {
@ -68,11 +72,16 @@ lazy_static! {
} }
#[derive(Debug, clap::Parser)] #[derive(Debug, clap::Parser)]
#[command(version, about, long_about = None)]
struct Args { struct Args {
/// Width of the output images (pixel-widths)
width: u16, width: u16,
/// Width of the output images (pixel-widths)
height: u16, height: u16,
/// Prefix for image paths; ex: /tmp/example- -> /tmp/example-000.png ...
#[arg(short, long)] #[arg(short, long)]
output_file: PathBuf, output_prefix: String,
/// How many steps to run the automata
#[arg(short, long)] #[arg(short, long)]
steps: u64, steps: u64,
} }
@ -142,8 +151,8 @@ impl Game {
} }
} }
impl From<Game> for ImageBuffer<Rgb<u8>, Vec<u8>> { impl From<&Game> for ImageBuffer<Rgb<u8>, Vec<u8>> {
fn from(val: Game) -> Self { fn from(val: &Game) -> Self {
ImageBuffer::from_fn(val.width as u32, val.height as u32, |x, y| { ImageBuffer::from_fn(val.width as u32, val.height as u32, |x, y| {
val.at(i64::from(x), i64::from(y)).unwrap().color() val.at(i64::from(x), i64::from(y)).unwrap().color()
}) })