canvas: enable saving to PNG.
This commit is contained in:
parent
536b6bed1f
commit
7786aa99a1
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user