data_access_layer/
images.rs1use image::io::Reader as ImageReader;
4use image::{ImageBuffer, Rgb, DynamicImage};
5use crate::tags::SurgeryStep;
6use std::io::{self, Write};
7
8
9#[derive(Debug)]
16struct RgbIndexes {
17 red: usize,
18 green: usize,
19 blue: usize,
20}
21
22
23fn calculate_rgb_index(x: usize, y: usize, total_width: usize, total_height: usize) -> RgbIndexes {
34 RgbIndexes {
35 red: 0 * total_height * total_width + y * total_width + x,
36 green: 1 * total_height * total_width + y * total_width + x,
37 blue: 2 * total_height * total_width + y * total_width + x,
38 }
39}
40
41
42pub fn read_rgb_image(path: String, height: usize, width: usize) -> Vec<u8> {
53 let depth: usize = 3;
56
57 let img: DynamicImage = ImageReader::open(path).unwrap().decode().unwrap();
58 let resized_img: DynamicImage = img.resize_exact(width as u32, height as u32, image::imageops::FilterType::Nearest);
59
60 let rgb_img: ImageBuffer<Rgb<u8>, Vec<u8>> = resized_img.to_rgb8();
62
63 let mut raw_data = vec![0u8; depth * height * width]; for chunk in rgb_img.enumerate_pixels() {
66 let x: u32 = chunk.0;
67 let y: u32 = chunk.1;
68 let pixel: &Rgb<u8> = chunk.2; let indexes = calculate_rgb_index(x as usize, y as usize, width, height);
71
72 raw_data[indexes.red as usize] = pixel[0]; raw_data[indexes.green as usize] = pixel[1]; raw_data[indexes.blue as usize] = pixel[2]; }
76 raw_data
77}
78
79
80pub fn write_frame_to_std_out(data: Vec<u8>, tag: SurgeryStep) {
86 let stdout = io::stdout();
87 let mut handle = stdout.lock();
88
89 handle.write_all(&(tag.to_u8() as u16).to_le_bytes()).unwrap();
91
92 handle.write_all(&(data.len() as u32).to_le_bytes()).unwrap();
94
95 for byte in data {
97 handle.write_all(&(byte as u16).to_le_bytes()).unwrap();
98 }
99
100 handle.flush().unwrap();
101}
102
103
104#[cfg(test)]
105mod tests {
106
107 use super::*;
108 use serde::Deserialize;
109
110 #[derive(Debug, Deserialize)]
111 struct DummyJson {
112 data: Vec<u8>,
113 }
114
115 #[test]
116 fn test_read_image() {
117 let _data = read_rgb_image("./data_stash/images/169_6300.jpg".to_string(), 480, 853);
118 }
119
120 #[test]
121 fn test_calculate_rgb_index() {
122
123 let total_height = 5;
125 let total_width = 10;
126
127 let indexes = calculate_rgb_index(0, 0, total_width, total_height);
128 assert_eq!(&0, &indexes.red);
129 assert_eq!(&50, &indexes.green);
130 assert_eq!(&100, &indexes.blue);
131
132 let indexes = calculate_rgb_index(1, 0, total_width, total_height);
133 assert_eq!(&1, &indexes.red);
134 assert_eq!(&51, &indexes.green);
135 assert_eq!(&101, &indexes.blue);
136
137 let indexes = calculate_rgb_index(2, 0, total_width, total_height);
138 assert_eq!(&2, &indexes.red);
139 assert_eq!(&52, &indexes.green);
140 assert_eq!(&102, &indexes.blue);
141
142 let indexes = calculate_rgb_index(0, 1, total_width, total_height);
143 assert_eq!(&10, &indexes.red);
144 assert_eq!(&60, &indexes.green);
145 assert_eq!(&110, &indexes.blue);
146
147 let indexes = calculate_rgb_index(0, 2, total_width, total_height);
148 assert_eq!(&20, &indexes.red);
149 assert_eq!(&70, &indexes.green);
150 assert_eq!(&120, &indexes.blue);
151 }
152
153 #[test]
154 fn test_test_calculate_rgb_index_quality_control() {
155 let raw_data = std::fs::read_to_string("./data_stash/images/dummy_rgb_data.json").unwrap();
156 let data: DummyJson = serde_json::from_str(&raw_data).unwrap();
157
158 let total_height = 5;
160 let total_width = 10;
161
162 let index = calculate_rgb_index(0, 0, total_width, total_height);
163 assert_eq!(&data.data[index.red], &111); assert_eq!(&data.data[index.green], &208); assert_eq!(&data.data[index.blue], &12); let index = calculate_rgb_index(5, 3, total_width, total_height);
168 assert_eq!(&data.data[index.red], &65);
169 assert_eq!(&data.data[index.green], &7);
170 assert_eq!(&data.data[index.blue], &193);
171
172 let index = calculate_rgb_index(8, 2, total_width, total_height);
173 assert_eq!(&data.data[index.red], &253);
174 assert_eq!(&data.data[index.green], &133);
175 assert_eq!(&data.data[index.blue], &115);
176 }
177}