From 591dbb7c532f2e794488b7ffaebb372e00f0c261 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 1 Nov 2021 23:09:01 -0400 Subject: Write animation frames to a pipe rather than separate files --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 41 +++++++++++++++++++++++++---------------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc30b5b..41db677 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,6 +256,7 @@ name = "kd-forest" version = "2.0.0" dependencies = [ "acap", + "atty", "clap", "image", "rand", diff --git a/Cargo.toml b/Cargo.toml index f8c2b8b..36d8478 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] acap = "0.3.0" +atty = "0.2.14" clap = "2.33.3" image = "0.23.14" rand = "0.8.4" diff --git a/src/main.rs b/src/main.rs index adb05b1..d4c39fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,15 +13,15 @@ use crate::frontier::Frontier; use clap::{self, clap_app, crate_authors, crate_name, crate_version}; -use image::{self, ImageError, Rgba, RgbaImage}; +use image::{self, ColorType, ImageError, Rgba, RgbaImage}; +use image::png::PngEncoder; use rand::{self, SeedableRng}; use rand_pcg::Pcg64; use std::cmp; use std::error::Error; -use std::fs; -use std::io::{self, Write}; +use std::io::{self, BufWriter, Write}; use std::path::PathBuf; use std::process::exit; use std::str::FromStr; @@ -264,12 +264,9 @@ impl Args { let animate = args.is_present("ANIMATE"); - let path = if animate && args.occurrences_of("PATH") == 0 { - "kd-frames" - } else { - args.value_of("PATH").unwrap() - }; - let output = PathBuf::from(path); + let output = args.value_of("PATH") + .map(PathBuf::from) + .unwrap(); let seed = parse_arg(args.value_of("SEED"))?.unwrap_or(0); @@ -385,17 +382,31 @@ impl App { } } + fn write_frame(image: &RgbaImage) -> AppResult<()> { + if atty::is(atty::Stream::Stdout) { + return Err(AppError::invalid_value( + "Not writing images to your terminal, please pipe the output somewhere" + )); + } + + let stdout = io::stdout(); + let writer = BufWriter::new(stdout.lock()); + let encoder = PngEncoder::new(writer); + encoder.encode(image, image.width(), image.height(), ColorType::Rgba8)?; + + Ok(()) + } + fn paint_on(&mut self, colors: Vec, mut frontier: F) -> AppResult<()> { let width = frontier.width(); let height = frontier.height(); let mut output = RgbaImage::new(width, height); let size = cmp::min((width * height) as usize, colors.len()); - println!("Generating a {}x{} image ({} pixels)", width, height, size); + eprintln!("Generating a {}x{} image ({} pixels)", width, height, size); if self.args.animate { - fs::create_dir_all(&self.args.output)?; - output.save(&self.args.output.join("0000.png"))?; + Self::write_frame(&output)?; } let interval = cmp::max(width, height) as usize; @@ -416,8 +427,7 @@ impl App { if (i + 1) % interval == 0 { if self.args.animate { - let frame = (i + 1) / interval; - output.save(&self.args.output.join(format!("{:04}.png", frame)))?; + Self::write_frame(&output)?; } if i + 1 < size { @@ -427,8 +437,7 @@ impl App { } if self.args.animate && size % interval != 0 { - let frame = size / interval; - output.save(&self.args.output.join(format!("{:04}.png", frame)))?; + Self::write_frame(&output)?; } self.print_progress(size, size, max_frontier)?; -- cgit v1.2.3