launchkey_sdk/launchkey/
bitmap.rs1use image::DynamicImage;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct LaunchkeyBitmap([u8; 1216]);
6
7impl LaunchkeyBitmap {
8 pub fn new(data: [u8; 1216]) -> Self {
10 Self(data)
11 }
12
13 pub fn from_image(img: DynamicImage, threshold: u8) -> Result<Self, String> {
15 const DISPLAY_WIDTH: u32 = 128;
16 const DISPLAY_HEIGHT: u32 = 64;
17 const BYTES_PER_ROW: u32 = 19;
18
19 let img = img.resize_exact(DISPLAY_WIDTH, DISPLAY_HEIGHT, image::imageops::Nearest);
20 let img = img.to_luma8();
21
22 let mut data = [0u8; 1216];
23
24 for y in 0..DISPLAY_HEIGHT {
25 for x in 0..DISPLAY_WIDTH {
26 let pixel = img.get_pixel(x, y)[0];
27 if pixel > threshold {
28 let byte_index = ((y * BYTES_PER_ROW) + (x / 7)) as usize;
29 let bit_offset = 6 - (x % 7); data[byte_index] |= 1 << bit_offset;
31 }
32 }
33 }
34
35 Ok(Self(data))
36 }
37}
38
39impl TryFrom<&[u8]> for LaunchkeyBitmap {
40 type Error = String;
41
42 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
43 if value.len() != 1216 {
44 Err(format!("Invalid length: {} (must be 1216)", value.len()))
45 } else {
46 let mut buffer = [0u8; 1216];
47 buffer.copy_from_slice(value);
48 Ok(Self(buffer))
49 }
50 }
51}
52
53impl From<LaunchkeyBitmap> for [u8; 1216] {
54 fn from(val: LaunchkeyBitmap) -> Self {
55 val.0
56 }
57}
58
59impl AsRef<[u8; 1216]> for LaunchkeyBitmap {
60 fn as_ref(&self) -> &[u8; 1216] {
61 &self.0
62 }
63}