agent_image_diff/
antialias.rs1use image::RgbaImage;
2
3use crate::color;
4
5pub fn is_antialiased(
14 img: &RgbaImage,
15 other: &RgbaImage,
16 x: u32,
17 y: u32,
18) -> bool {
19 let (width, height) = img.dimensions();
20 let center = img.get_pixel(x, y).0;
21
22 let mut identical_count = 0;
23 let mut min_y_delta = 0.0_f64;
24 let mut max_y_delta = 0.0_f64;
25 let mut min_x = x;
26 let mut min_y_coord = y;
27 let mut max_x = x;
28 let mut max_y_coord = y;
29
30 for dy in -1i32..=1 {
32 for dx in -1i32..=1 {
33 if dx == 0 && dy == 0 {
34 continue;
35 }
36 let nx = x as i32 + dx;
37 let ny = y as i32 + dy;
38 if nx < 0 || ny < 0 || nx >= width as i32 || ny >= height as i32 {
39 continue;
40 }
41 let nx = nx as u32;
42 let ny = ny as u32;
43 let neighbor = img.get_pixel(nx, ny).0;
44
45 if center == neighbor {
47 identical_count += 1;
48 if identical_count >= 3 {
49 return false; }
51 continue;
52 }
53
54 let y_delta = color::color_delta(center, neighbor, true);
56
57 if y_delta < min_y_delta {
58 min_y_delta = y_delta;
59 min_x = nx;
60 min_y_coord = ny;
61 }
62 if y_delta > max_y_delta {
63 max_y_delta = y_delta;
64 max_x = nx;
65 max_y_coord = ny;
66 }
67 }
68 }
69
70 if min_y_delta >= 0.0 || max_y_delta <= 0.0 {
72 return false;
73 }
74
75 has_many_identical_neighbors(other, min_x, min_y_coord)
77 && has_many_identical_neighbors(other, max_x, max_y_coord)
78}
79
80fn has_many_identical_neighbors(img: &RgbaImage, x: u32, y: u32) -> bool {
82 let (width, height) = img.dimensions();
83 if x >= width || y >= height {
84 return false;
85 }
86 let center = img.get_pixel(x, y).0;
87 let mut count = 0;
88
89 for dy in -1i32..=1 {
90 for dx in -1i32..=1 {
91 if dx == 0 && dy == 0 {
92 continue;
93 }
94 let nx = x as i32 + dx;
95 let ny = y as i32 + dy;
96 if nx < 0 || ny < 0 || nx >= width as i32 || ny >= height as i32 {
97 continue;
98 }
99 if img.get_pixel(nx as u32, ny as u32).0 == center {
100 count += 1;
101 if count >= 3 {
102 return true;
103 }
104 }
105 }
106 }
107 false
108}