12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- pub type Pixel = (u8, u8, u8);
- pub struct Image {
- pub width: u32,
- pub height: u32,
- data: Vec<Pixel>,
- }
- impl Image {
- pub fn load(path: impl AsRef<std::path::Path>) -> Result<Image, Box<dyn std::error::Error>> {
- let decoder = png::Decoder::new(std::fs::File::open(path)?);
- let mut reader = decoder.read_info()?;
- let mut buf = vec![0u8; reader.output_buffer_size()];
- let info = reader.next_frame(buf.as_mut_slice())?;
- let mut data = Vec::new();
- let skip = match info.color_type {
- png::ColorType::Rgb => 3,
- png::ColorType::Rgba => 4,
- other => panic!("Unhandled color type: {:?}", other),
- };
- let rs = buf.iter().step_by(skip);
- let gs = buf.iter().skip(1).step_by(skip);
- let bs = buf.iter().skip(2).step_by(skip);
- for ((r, g), b) in rs.zip(gs).zip(bs) {
- data.push((*r, *g, *b))
- }
- Ok(Image {
- width: info.width,
- height: info.height,
- data,
- })
- }
- pub fn iter(&self) -> ImageIterator {
- ImageIterator {
- width: self.width,
- x: 0,
- y: 0,
- values: self.data.iter(),
- }
- }
- }
- pub struct ImageIterator<'a> {
- width: u32,
- x: u32,
- y: u32,
- values: std::slice::Iter<'a, Pixel>,
- }
- impl<'a> Iterator for ImageIterator<'a> {
- type Item = ((u32, u32), Pixel);
- fn next(&mut self) -> Option<Self::Item> {
- let px = self.values.next();
- if let Some(px) = px {
- let ret = ((self.x, self.y), *px);
- self.x += 1;
- if self.x == self.width {
- self.x = 0;
- self.y += 1;
- }
- Some(ret)
- } else {
- None
- }
- }
- }
|