1 use std::{ 2 cell::Cell, 3 cmp, 4 fs::File, 5 io::{Seek, SeekFrom, Write}, 6 mem, ptr, 7 }; 8 9 use image::GenericImageView; 10 use starry_client::base::{ 11 color::Color, 12 renderer::{RenderMode, Renderer}, 13 }; 14 15 use crate::core::{SCREEN_HEIGHT, SCREEN_WIDTH}; 16 17 use super::rect::Rect; 18 19 /// Roi区域中的行数据 20 pub struct ImageRoiRows<'a> { 21 /// Roi矩形区域(相对位置) 22 rect: Rect, 23 /// 矩形宽度 24 w: i32, 25 /// 帧缓冲数据 26 data: &'a [Color], 27 /// 当前行号 28 i: i32, 29 } 30 31 // 实现迭代器 32 impl<'a> Iterator for ImageRoiRows<'a> { 33 type Item = &'a [Color]; 34 fn next(&mut self) -> Option<Self::Item> { 35 if self.i < self.rect.height() { 36 let start = (self.rect.top() + self.i) * self.w + self.rect.left(); 37 let end = start + self.rect.width(); 38 self.i += 1; 39 Some(&self.data[start as usize..end as usize]) 40 } else { 41 None 42 } 43 } 44 } 45 46 /// Roi区域中的行数据 47 pub struct ImageRoiRowsMut<'a> { 48 /// Roi矩形区域(相对位置) 49 rect: Rect, 50 /// 矩形宽度 51 w: i32, 52 /// 帧缓冲数据 53 data: &'a mut [Color], 54 /// 当前行号 55 i: i32, 56 } 57 58 // 实现迭代器 59 impl<'a> Iterator for ImageRoiRowsMut<'a> { 60 type Item = &'a mut [Color]; 61 fn next(&mut self) -> Option<Self::Item> { 62 if self.i < self.rect.height() { 63 let mut data = mem::take(&mut self.data); 64 65 // 剔除掉矩形以上的部分 66 if self.i == 0 { 67 data = data 68 .split_at_mut(self.rect.top() as usize * self.w as usize) 69 .1 70 }; 71 72 // 分离当前行和剩下的部分 73 let (row, tail) = data.split_at_mut(self.w as usize); 74 self.data = tail; 75 let start = self.rect.left() as usize; 76 let end = self.rect.left() as usize + self.rect.width() as usize; 77 self.i += 1; 78 Some(&mut row[start..end]) 79 } else { 80 None 81 } 82 } 83 } 84 85 /// 图像中的ROI区域 86 pub struct ImageRoi<'a> { 87 /// ROI矩形区域(相对位置) 88 rect: Rect, 89 /// 矩形区域宽度 90 w: i32, 91 /// 帧缓冲数据 92 data: &'a mut [Color], 93 } 94 95 // 实现到迭代器的转换 96 impl<'a> IntoIterator for ImageRoi<'a> { 97 type Item = &'a [Color]; 98 type IntoIter = ImageRoiRows<'a>; 99 100 fn into_iter(self) -> Self::IntoIter { 101 let Self { rect, w, data } = self; 102 // 两次切片操作 103 let data = 104 &mut data[rect.top() as usize * w as usize..][..rect.height() as usize * w as usize]; 105 ImageRoiRows { 106 rect, 107 w, 108 data, 109 i: 0, 110 } 111 } 112 } 113 114 impl<'a> ImageRoi<'a> { 115 /// 获得Roi相应的行数据 116 pub fn rows(&'a self) -> ImageRoiRows<'a> { 117 ImageRoiRows { 118 rect: self.rect, 119 w: self.w, 120 data: self.data, 121 i: 0, 122 } 123 } 124 125 /// 获得Roi相应的行数据 126 pub fn rows_mut(&'a mut self) -> ImageRoiRowsMut<'a> { 127 ImageRoiRowsMut { 128 rect: self.rect, 129 w: self.w, 130 data: self.data, 131 i: 0, 132 } 133 } 134 135 /// Roi区域颜色混合 136 pub fn blend(&'a mut self, other: &ImageRoi) { 137 for (self_row, other_row) in self.rows_mut().zip(other.rows()) { 138 for (old, new) in self_row.iter_mut().zip(other_row.iter()) { 139 let alpha = (new.data >> 24) & 0xFF; 140 if alpha >= 255 { 141 old.data = new.data; 142 } else if alpha > 0 { 143 let n_r = (((new.data >> 16) & 0xFF) * alpha) >> 8; 144 let n_g = (((new.data >> 8) & 0xFF) * alpha) >> 8; 145 let n_b = ((new.data & 0xFF) * alpha) >> 8; 146 147 let n_alpha = 255 - alpha; 148 149 let o_r = (((old.data >> 16) & 0xFF) * n_alpha) >> 8; 150 let o_g = (((old.data >> 8) & 0xFF) * n_alpha) >> 8; 151 let o_b = ((old.data & 0xFF) * n_alpha) >> 8; 152 153 old.data = ((o_r << 16) | (o_g << 8) | o_b) + ((n_r << 16) | (n_g << 8) | n_b); 154 } 155 } 156 } 157 } 158 159 /// Roi区域颜色覆盖 160 pub fn cover(&'a mut self, other: &ImageRoi) { 161 for (self_row, other_row) in self.rows_mut().zip(other.rows()) { 162 let len = cmp::min(self_row.len(), other_row.len()); 163 unsafe { 164 ptr::copy(other_row.as_ptr(), self_row.as_mut_ptr(), len); 165 } 166 } 167 } 168 } 169 170 /// 包含帧缓冲区的图像 171 pub struct ImageRef<'a> { 172 w: i32, 173 h: i32, 174 data: &'a mut [Color], 175 mode: Cell<RenderMode>, 176 } 177 178 impl<'a> ImageRef<'a> { 179 /// 根据帧缓冲数据创建新图像 180 pub fn from_data(width: i32, height: i32, data: &'a mut [Color]) -> Self { 181 ImageRef { 182 w: width, 183 h: height, 184 data, 185 mode: Cell::new(RenderMode::Blend), 186 } 187 } 188 189 /// 获得图像宽度 190 pub fn width(&self) -> i32 { 191 self.w 192 } 193 194 /// 获得图像高度 195 pub fn height(&self) -> i32 { 196 self.h 197 } 198 199 /// 根据矩形区域返回相应的Roi 200 pub fn roi(&mut self, rect: &Rect) -> ImageRoi { 201 ImageRoi { 202 rect: *rect, 203 w: self.w, 204 data: &mut self.data, 205 } 206 } 207 } 208 209 impl<'a> Renderer for ImageRef<'a> { 210 fn width(&self) -> u32 { 211 self.w as u32 212 } 213 214 fn height(&self) -> u32 { 215 self.h as u32 216 } 217 218 fn data(&self) -> &[Color] { 219 self.data 220 } 221 222 fn data_mut(&mut self) -> &mut [Color] { 223 self.data 224 } 225 226 fn sync(&mut self) -> bool { 227 true 228 } 229 230 fn mode(&self) -> &Cell<RenderMode> { 231 &self.mode 232 } 233 } 234 235 /// 包含帧缓冲区的图像 236 #[derive(Clone)] 237 pub struct Image { 238 /// 宽度 239 w: i32, 240 /// 高度 241 h: i32, 242 /// 像素数据 243 data: Box<[Color]>, 244 /// 渲染模式 245 mode: Cell<RenderMode>, 246 } 247 248 impl Image { 249 /// 创建默认图像 250 pub fn new(width: i32, height: i32) -> Self { 251 Image::from_color(width, height, Color::rgb(0, 0, 0)) 252 } 253 254 /// 创建单一颜色的图像 255 pub fn from_color(width: i32, height: i32, color: Color) -> Self { 256 Image::from_data( 257 width, 258 height, 259 vec![color; (width * height) as usize].into_boxed_slice(), 260 ) 261 } 262 263 /// 根据帧缓冲数据创建新图像 264 pub fn from_data(width: i32, height: i32, data: Box<[Color]>) -> Self { 265 Image { 266 w: width, 267 h: height, 268 data, 269 mode: Cell::new(RenderMode::Blend), 270 } 271 } 272 273 pub fn from_path_scale(path: &[u8]) -> Option<Self> { 274 if let Ok(mut img) = image::load_from_memory(path) { 275 // let img = img.resize(20, 20, image::imageops::FilterType::Gaussian); 276 277 let (mut img_width, mut img_heigh) = img.dimensions(); 278 if img_width > SCREEN_WIDTH as u32 || img_heigh > SCREEN_HEIGHT as u32 { 279 img = img.resize( 280 SCREEN_WIDTH as u32, 281 SCREEN_HEIGHT as u32, 282 image::imageops::FilterType::Gaussian, 283 ); 284 (img_width, img_heigh) = img.dimensions(); 285 } 286 287 let mut image = Image::new(img_width as i32, img_heigh as i32); 288 for y in 0..img_heigh { 289 for x in 0..img_width as u32 { 290 let pixel = img.get_pixel(x, y); 291 let offset = y * img_width + x; 292 // println!("Cursor pixel print x:{:?} y:{:?} rgba:{:?} {:?} {:?} {:?}", x, y, pixel[0], pixel[1], pixel[2], pixel[3]); 293 image.data[offset as usize] = 294 Color::rgba(pixel[0], pixel[1], pixel[2], pixel[3]); 295 } 296 } 297 298 // println!( 299 // "[Info] Image created from path successfully, width: {:?} height: {:?}", 300 // img_width, img_heigh 301 // ); 302 303 return Some(image); 304 } else { 305 println!("[Error] Image created from path failed"); 306 return None; 307 } 308 } 309 310 /// 返回图像宽度 311 pub fn width(&self) -> i32 { 312 self.w 313 } 314 315 /// 返回图像高度 316 pub fn height(&self) -> i32 { 317 self.h 318 } 319 320 /// 返回图像宽度和高度 321 pub fn dimensions(&self) -> (i32, i32) { 322 (self.w, self.h) 323 } 324 325 /// # 函数功能 326 /// 根据矩形区域返回相应的Roi 327 /// 328 /// ## 参数值 329 /// - rect: 矩形区域(相对位置) 330 /// 331 /// ## 返回值 332 /// Roi对象 333 pub fn roi(&mut self, rect: &Rect) -> ImageRoi { 334 ImageRoi { 335 rect: *rect, 336 w: self.w, 337 data: &mut self.data, 338 } 339 } 340 341 /// 展示在桌面中央 342 pub fn show_on_desktop(&self) { 343 let xoffset = (SCREEN_WIDTH as i32 - self.width()) / 2; 344 let yoffset = (SCREEN_HEIGHT as i32 - self.height()) / 2; 345 let mut fb = File::open("/dev/fb0").expect("[Error] Unable to open framebuffer"); 346 for y in 0..self.height() { 347 for x in 0..self.width() { 348 let index: i32 = y * self.width() + x; 349 let offset = ((y + yoffset) * SCREEN_WIDTH as i32 + x + xoffset) * 4; 350 let color = &self.data[index as usize]; 351 println!( 352 "Image show print x:{:?} y:{:?} rgba:{:?} {:?} {:?} {:?}", 353 x, 354 y, 355 color.r(), 356 color.g(), 357 color.b(), 358 color.a() 359 ); 360 fb.seek(SeekFrom::Start(offset as u64)).expect("error"); 361 fb.write(&self.data[index as usize].to_bgra_bytes()) 362 .expect("error"); 363 } 364 } 365 } 366 } 367 368 impl Renderer for Image { 369 fn width(&self) -> u32 { 370 self.w as u32 371 } 372 373 fn height(&self) -> u32 { 374 self.h as u32 375 } 376 377 fn data(&self) -> &[Color] { 378 &self.data 379 } 380 381 fn data_mut(&mut self) -> &mut [Color] { 382 &mut self.data 383 } 384 385 fn mode(&self) -> &Cell<RenderMode> { 386 &self.mode 387 } 388 389 fn sync(&mut self) -> bool { 390 true 391 } 392 } 393