canvas: enable saving to PNG.

This commit is contained in:
Bill Thiede 2021-06-24 16:40:33 -07:00
parent 536b6bed1f
commit 7786aa99a1

View File

@ -1,12 +1,26 @@
use std::fs::File;
use std::io::BufWriter;
use std::path::Path;
use png;
use thiserror::Error;
use crate::tuples::{color, Color};
#[derive(Error, Debug)]
pub enum CanvasError {
#[error("faile to write canvas")]
IOError(#[from] std::io::Error),
#[error("faile to encode canvas to png")]
EncodingError(#[from] png::EncodingError),
}
pub struct Canvas {
pub height: usize,
pub width: usize,
pub pixels: Vec<Color>,
}
fn canvas(width: usize, height: usize) -> Canvas {
pub fn canvas(width: usize, height: usize) -> Canvas {
let pixels = vec![color(0., 0., 0.); width * height];
Canvas {
width,
@ -17,11 +31,44 @@ fn canvas(width: usize, height: usize) -> Canvas {
impl Canvas {
pub fn set(&mut self, x: usize, y: usize, c: Color) {
if x > self.width {
return;
}
if y > self.height {
return;
}
self.pixels[x + y * self.width] = c;
}
pub fn get(&mut self, x: usize, y: usize) -> Color {
self.pixels[x + y * self.width]
}
pub fn write_to_file<P>(&self, path: P) -> Result<(), CanvasError>
where
P: AsRef<Path>,
{
let path = Path::new(path.as_ref());
let file = File::create(path)?;
let ref mut w = BufWriter::new(file);
let mut encoder = png::Encoder::new(w, self.width as u32, self.height as u32);
encoder.set_color(png::ColorType::RGB);
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header()?;
let data: Vec<u8> = self
.pixels
.iter()
.flat_map(|p| {
vec![
(p.red.clamp(0., 1.) * 255.) as u8,
(p.green.clamp(0., 1.) * 255.) as u8,
(p.blue.clamp(0., 1.) * 255.) as u8,
]
})
.collect();
writer.write_image_data(&data)?;
Ok(())
}
}
#[cfg(test)]
mod tests {