(&mut self, accumulated: Vec<Coord<f64>>)
| 120 | } |
| 121 | |
| 122 | fn write_image(&mut self, accumulated: Vec<Coord<f64>>) -> eyre::Result<()> { |
| 123 | let accumulated = LineString::from(accumulated); |
| 124 | let bbox = accumulated.bounding_rect().ok_or_else(|| { |
| 125 | eyre::eyre!("Cannot determine bounding box of accumulated coordinates") |
| 126 | })?; |
| 127 | let (width, height) = self.determine_image_size(&bbox); |
| 128 | |
| 129 | // Padding is to avoid off-by-one errors due to rounding floats -> int |
| 130 | let mut image = image::GrayImage::new(width + 1, height + 1); |
| 131 | for pixel in image.pixels_mut() { |
| 132 | pixel.0[0] = 255; // white |
| 133 | // I struggled using GrayAlphaImage and setting the alpha values correctly. Maybe I'll |
| 134 | // revisit that later. For now, just darken the pixels on each visit. |
| 135 | } |
| 136 | for coord in accumulated { |
| 137 | let (x, y) = Self::map_coordinate_to_pixel(&coord, &bbox, width, height); |
| 138 | let pixel = image.get_pixel_mut(x, y); |
| 139 | pixel.0[0] = pixel.0[0].saturating_sub(64); // darken the pixel, but don't wrap around! |
| 140 | } |
| 141 | |
| 142 | image.save_with_format(self.output.as_ref().unwrap(), image::ImageFormat::Png)?; |
| 143 | |
| 144 | Ok(()) |
| 145 | } |
| 146 | |
| 147 | fn determine_image_size(&self, bbox: &geo::Rect) -> (u32, u32) { |
| 148 | let coord_width = bbox.max().x - bbox.min().x; |
no test coverage detected