42 lines
987 B
Rust
42 lines
987 B
Rust
|
use std::io::{Result, Write};
|
||
|
|
||
|
use nalgebra::Vector3;
|
||
|
|
||
|
/// A pixel color represented by a red, green, and blue value in the range 0-1.
|
||
|
pub type Color = Vector3<f64>;
|
||
|
|
||
|
/// A representation of an image
|
||
|
pub struct Image {
|
||
|
/// Width in pixels
|
||
|
pub(crate) width: usize,
|
||
|
|
||
|
/// Height in pixels
|
||
|
pub(crate) height: usize,
|
||
|
|
||
|
/// Pixel data in row-major form.
|
||
|
pub(crate) data: Vec<Color>,
|
||
|
}
|
||
|
|
||
|
impl Image {
|
||
|
/// Write the image in PPM format to a file.
|
||
|
pub fn write(&self, mut w: impl Write) -> Result<()> {
|
||
|
// Header
|
||
|
let header = format!("P3 {} {} 255\n", self.width, self.height);
|
||
|
w.write_all(header.as_bytes())?;
|
||
|
|
||
|
// Pixel data
|
||
|
assert_eq!(self.data.len(), self.width * self.height);
|
||
|
|
||
|
for pixel in self.data.iter() {
|
||
|
let pixel = pixel * 256.0;
|
||
|
let red = pixel.x as u8;
|
||
|
let green = pixel.y as u8;
|
||
|
let blue = pixel.z as u8;
|
||
|
let pixel = format!("{red} {green} {blue}\n");
|
||
|
w.write_all(pixel.as_bytes())?;
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|