summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2021-11-01 23:09:01 -0400
committerTavian Barnes <tavianator@tavianator.com>2021-11-01 23:09:01 -0400
commit591dbb7c532f2e794488b7ffaebb372e00f0c261 (patch)
treeee4315587ae6501b02633fd1f43ea552e5c9e26f
parent41441fcbc4bc097a59383d88f0f79dbf64f66c9b (diff)
downloadkd-forest-591dbb7c532f2e794488b7ffaebb372e00f0c261.tar.xz
Write animation frames to a pipe rather than separate files
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs41
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<F: Frontier>(&mut self, colors: Vec<Rgb8>, 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)?;