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