image.rs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. pub type Pixel = (u8, u8, u8);
  2. pub struct Image {
  3. pub width: u32,
  4. pub height: u32,
  5. data: Vec<Pixel>,
  6. }
  7. impl Image {
  8. pub fn load(path: impl AsRef<std::path::Path>) -> Result<Image, Box<dyn std::error::Error>> {
  9. let decoder = png::Decoder::new(std::fs::File::open(path)?);
  10. let mut reader = decoder.read_info()?;
  11. let mut buf = vec![0u8; reader.output_buffer_size()];
  12. let info = reader.next_frame(buf.as_mut_slice())?;
  13. let mut data = Vec::new();
  14. let skip = match info.color_type {
  15. png::ColorType::Rgb => 3,
  16. png::ColorType::Rgba => 4,
  17. other => panic!("Unhandled color type: {:?}", other),
  18. };
  19. let rs = buf.iter().step_by(skip);
  20. let gs = buf.iter().skip(1).step_by(skip);
  21. let bs = buf.iter().skip(2).step_by(skip);
  22. for ((r, g), b) in rs.zip(gs).zip(bs) {
  23. data.push((*r, *g, *b))
  24. }
  25. Ok(Image {
  26. width: info.width,
  27. height: info.height,
  28. data,
  29. })
  30. }
  31. pub fn iter(&self) -> ImageIterator {
  32. ImageIterator {
  33. width: self.width,
  34. x: 0,
  35. y: 0,
  36. values: self.data.iter(),
  37. }
  38. }
  39. }
  40. pub struct ImageIterator<'a> {
  41. width: u32,
  42. x: u32,
  43. y: u32,
  44. values: std::slice::Iter<'a, Pixel>,
  45. }
  46. impl<'a> Iterator for ImageIterator<'a> {
  47. type Item = ((u32, u32), Pixel);
  48. fn next(&mut self) -> Option<Self::Item> {
  49. let px = self.values.next();
  50. if let Some(px) = px {
  51. let ret = ((self.x, self.y), *px);
  52. self.x += 1;
  53. if self.x == self.width {
  54. self.x = 0;
  55. self.y += 1;
  56. }
  57. Some(ret)
  58. } else {
  59. None
  60. }
  61. }
  62. }