arctk/parse/
png.rs

1//! Portable Network Graphics.
2
3use ndarray::{Array2, ArrayView2};
4use palette::{LinSrgba, Pixel};
5use png::{BitDepth, ColorType, Encoder};
6use slice_of_array::SliceFlatExt;
7use std::{fs::File, io::BufWriter, path::Path};
8
9/// Save an array as a PNG file.
10#[inline]
11pub fn save(image: ArrayView2<LinSrgba>, path: &Path) {
12    // Convert to png rgb space.
13    let res = image.shape();
14    let mut data: Array2<[u8; 4]> = Array2::from_elem((res[1], res[0]), [0; 4]);
15    for xi in 0..res[0] {
16        for yi in 0..res[1] {
17            data[(res[1] - yi - 1, xi)] = image[(xi, yi)].into_format().into_raw();
18        }
19    }
20
21    // Save data at path.
22    let file = File::create(path)
23        .unwrap_or_else(|_| panic!("Failed to create PNG file: {}", path.display()));
24    let w = BufWriter::new(file);
25    let mut encoder = Encoder::new(w, res[0] as u32, res[1] as u32);
26    encoder.set_color(ColorType::Rgba);
27    encoder.set_depth(BitDepth::Eight);
28    encoder
29        .write_header()
30        .expect("Failed to write PNG header.")
31        .write_image_data(data.into_raw_vec().flat())
32        .expect("Failed to write PNG data.");
33}