1use image::{ImageBuffer, Rgb};
2
3pub type Frame = Vec<u8>;
4pub type FrameBuffer = ImageBuffer<Rgb<u8>, Frame>;
5
6pub fn to_oled_bytes(frame_buffer: &FrameBuffer, brightness_threshold: u8) -> Vec<u8> {
22 let resized_img =
23 image::imageops::resize(frame_buffer, 128, 64, image::imageops::FilterType::Nearest);
24
25 resized_img
26 .chunks(3)
27 .fold(
28 (0, 0, 7_i32, resized_img.len(), Vec::<u8>::new()),
29 |(mut number, mut i, mut byte_index, pixels_len, mut oled_frame), rgb| {
30 let avg = rgb.iter().map(|x| *x as u16).sum::<u16>() / 3;
32
33 if avg > brightness_threshold.into() {
34 number += 2_u8.pow(byte_index as u32);
35 }
36
37 byte_index -= 1;
38
39 if (i != 0 && (((i / 3) + 1) % (128)) == 0) || (i == (pixels_len - 3)) {
42 byte_index = -1;
43 }
44
45 if byte_index < 0 {
47 oled_frame.push(number);
48 number = 0;
49 byte_index = 7;
50 }
51
52 i += 3;
53
54 (number, i, byte_index, pixels_len, oled_frame)
55 },
56 )
57 .4
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn it_returns_a_byte_vec_of_size_1024_for_any_size_frame_buffer() {
66 for i in [1, 4, 8, 16, 200, 400, 1000, 10000] {
67 let frame_buffer: ImageBuffer<Rgb<u8>, Vec<u8>> =
68 ImageBuffer::from_vec(i, i, vec![0; (i * i * 3) as usize]).unwrap();
69 let result = to_oled_bytes(&frame_buffer, 20);
70
71 assert_eq!(result.len(), 1024);
72 }
73 }
74
75 #[test]
76 fn it_uses_brightness_threshold_to_determine_number() {
77 let frame_buffer: ImageBuffer<Rgb<u8>, Vec<u8>> =
78 ImageBuffer::from_vec(2, 2, vec![30; 12]).unwrap();
79 let black_results = to_oled_bytes(&frame_buffer, 30);
80
81 assert_eq!(black_results, vec![0; 1024]);
82 assert_eq!(black_results.len(), 1024);
83
84 let white_results = to_oled_bytes(&frame_buffer, 20);
85
86 assert_eq!(white_results, vec![255; 1024]);
87 assert_eq!(white_results.len(), 1024);
88 }
89
90 #[test]
91 fn it_does_not_overflow_when_computing_average() {
92 let frame_buffer: ImageBuffer<Rgb<u8>, Vec<u8>> =
93 ImageBuffer::from_vec(640, 480, vec![255; (1024 * 1024 * 3) as usize]).unwrap();
94 let results = to_oled_bytes(&frame_buffer, 30);
95
96 assert_eq!(results, vec![255; 1024]);
97 assert_eq!(results.len(), 1024);
98 }
99}