1use crate::bin_image::*;
2use crate::common::*;
3use std::convert::TryFrom;
4use std::io::Error;
5#[cfg(test)]
6use std::path::PathBuf;
7
8pub fn imgthin(pixels: Vec<Vec<bool>>) -> Result<Vec<Vec<bool>>, Error> {
9 let bin_image_result = BinImage::try_from(pixels);
10
11 match bin_image_result {
12 Ok(mut image_mut) => {
13 let mut c = 0;
14 let mut first = true;
15 let width = image_mut.get_width();
16 let height = image_mut.get_height();
17
18 while c > 0 || first {
19 first = false;
20 let sub_iters = vec![SubIter::First, SubIter::Second];
21
22 for sub_iter in sub_iters {
23 if let SubIter::Second = sub_iter {
24 c = 0;
25 }
26
27 let mut m = BinImage::new(width, height, false);
28 let img_iter = image_mut.clone().into_iter();
29
30 for (x, y, _) in img_iter {
31 if image_mut.sub_iter(sub_iter.clone(), x, y)
32 && image_mut.get_value(x, y).unwrap()
33 {
34 let _result = m.set_value(x, y, true);
35 c += 1;
36 }
37 }
38
39 image_mut = image_mut - m;
40
41 if c == 0 {
42 break;
43 }
44 }
45 }
46 Ok(image_mut.get_pixels().to_vec())
47 }
48 Err(e) => Err(e),
49 }
50}
51
52#[cfg(test)]
53mod test {
54
55 use super::*;
56
57 #[test]
58 fn test_subiter() {
59 let img = BinImage::try_from(PathBuf::from("./test_data/test_subiter.txt")).unwrap();
60
61 assert_eq!(img.sub_iter(SubIter::First, 4, 4), false);
62 assert_eq!(img.sub_iter(SubIter::First, 3, 1), true);
63 assert_eq!(img.sub_iter(SubIter::Second, 3, 7), true);
64 assert_eq!(img.sub_iter(SubIter::Second, 3, 6), false);
65 }
66
67 #[test]
68 fn test_char_b() {
69 let img = BinImage::try_from(PathBuf::from("./test_data/b_char.txt")).unwrap();
70
71 let thinned = imgthin(img.get_pixels().to_vec()).unwrap();
72
73 let expect_img =
74 BinImage::try_from(PathBuf::from("./test_data/b_char_thinned.txt")).unwrap();
75 assert_eq!(expect_img.get_pixels(), &thinned);
76 }
77}