image_diff/
lib.rs

1use anyhow::Error;
2use image::{DynamicImage, GenericImage, GenericImageView, Rgba};
3use std::cmp::max;
4
5pub type Result<T> = std::result::Result<T, Error>;
6
7pub fn diff(before: &DynamicImage, after: &DynamicImage) -> Result<DynamicImage> {
8    let (after_width, after_height) = after.dimensions();
9    let (before_width, before_height) = before.dimensions();
10    let width = max(after_width, before_width);
11    let height = max(after_height, before_height);
12    let mut result = DynamicImage::new_rgba8(width, height);
13
14    for y in 0..height {
15        for x in 0..width {
16            let new_color: [u8; 4];
17            let pixel: Rgba<u8>;
18            if x >= before_width
19                || y >= before_height
20                || x >= after_width
21                || y >= after_height
22            {
23                new_color = [255, 0, 0, 255];
24                pixel = Rgba(new_color);
25            } else {
26                let before_pixel: Rgba<u8> = before.get_pixel(x, y);
27                let after_pixel: Rgba<u8> = after.get_pixel(x, y);
28                let alpha = before_pixel[3];
29
30                let is_diff = before_pixel[0] != after_pixel[0]
31                    || before_pixel[1] != after_pixel[1]
32                    || before_pixel[2] != after_pixel[2];
33
34                let mut new_red = after_pixel[0];
35                let mut new_green = after_pixel[1];
36                let mut new_blue = after_pixel[2];
37                if is_diff {
38                    new_red = 255;
39                    new_green = 0;
40                    new_blue = 0;
41                }
42
43                new_color = [new_red, new_green, new_blue, alpha];
44                pixel = Rgba(new_color);
45
46            }
47            result.put_pixel(x, y, pixel);
48        }
49    }
50    Ok(result)
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn test_diff() {
59        let before = image::open("test/before.png");
60        let after = image::open("test/after.png").unwrap();
61        let dif = diff(&before.unwrap(), &after);
62        assert_eq!(true, dif.is_ok());
63    }
64}