image_convolution/
image.rs

1use crate::Real;
2
3/// Row major image data
4pub struct Image {
5    pub data: Vec<Real>,
6    pub width: u32,
7    pub height: u32,
8}
9
10impl Image {
11    pub fn new(width: u32, height: u32, value: Real) -> Self {
12        let len = (width * height) as usize;
13        let data = vec![value; len];
14        Image {
15            width,
16            height,
17            data,
18        }
19    }
20
21    pub fn size(&self) -> u32 {
22        self.width * self.height
23    }
24
25    pub fn load<P: AsRef<std::path::Path>>(filepath: &P) -> Image {
26        let image = image::open(filepath).expect("read image file").into_luma8();
27        let (width, height) = image.dimensions();
28        let data = image.as_raw().iter().map(|pixel| *pixel as Real).collect();
29        Image {
30            data,
31            width,
32            height,
33        }
34    }
35
36    pub fn save<P: AsRef<std::path::Path>>(&self, filepath: P) {
37        let image = image::GrayImage::from_raw(
38            self.width,
39            self.height,
40            self.data.iter().map(|pixel| pixel.abs() as u8).collect(),
41        )
42        .expect("Create output image");
43        image.save(filepath).expect("write image file");
44    }
45}
46
47impl std::ops::Index<(u32, u32)> for Image {
48    type Output = Real;
49
50    #[inline]
51    fn index(&self, (x, y): (u32, u32)) -> &Self::Output {
52        let idx = (y * self.width + x) as usize;
53        &self.data[idx]
54    }
55}