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