e_utils/images/
mod.rs

1#![allow(deprecated)]
2use std::io::Cursor;
3
4use crate::{AnyRes, Result};
5use image::io::Reader;
6pub use image::{ColorType, DynamicImage, GenericImageView, ImageFormat};
7
8/// #枚举图像数据的来源
9/// # Example
10/// ```rust
11/// use e_utils::images::ImageSource;
12/// fn test() -> Result<()> {
13///   let file_image = ImageSource::File("D:\\1.jpeg".to_string()).to_image()?;
14///   let (width, height) = file_image.dimensions();
15///   println!("Image dimensions (from file): {} x {}", width, height);
16///   let url_image = ImageSource::Url(
17///     "http://q5.itc.cn/q_70/images03/20240222/d442108f65694b5081b0e793208a704c.jpeg".to_string(),
18///   )
19///   .to_image()?;
20///   let (width, height) = file_image.dimensions();
21///   println!("Image dimensions (from Url): {} x {}", width, height);
22///   url_image.save("D:\\url.jpeg")?;
23///   Ok(())
24/// }
25/// fn test2() -> Result<()>{
26///   // 从内存中获取数据
27///   let image = unsafe { ImageSource::from_raw_parts(pic_buf_ptr, (*size_returned) as usize) }
28///     .to_image()
29///     .to_tauri()?;
30///   // 获取图片数据
31///   let base64 = ImageSource::image_to_base64(&image);
32///   let bytes = ImageSource::image_into_bytes(image.clone());
33///   let (ptr, len) = ImageSource::image_to_ptr(image).to_tauri()?;
34///   let image = unsafe { ImageSource::from_raw_parts(ptr, len) };
35///   Ok(())
36/// }
37/// ```
38#[derive(Debug)]
39pub enum ImageSource<'a> {
40  /// 从文件加载图像,传入文件路径
41  File(String),
42  /// 从内存加载图像,传入图像数据的字节向量
43  Memory(&'a [u8]),
44  /// 从URL加载图像,传入URL地址
45  Url(String),
46  /// 从数据库加载图像,传入图像ID(假设)
47  Database(u64),
48  /// 从网络流加载图像,传入字节数据流
49  NetworkStream(Vec<u8>),
50}
51
52impl<'a> ImageSource<'a> {
53  /// 输出图像
54  pub fn to_image(self) -> Result<DynamicImage> {
55    Ok(match self {
56      ImageSource::File(file_path) => image::open(file_path).map_err(|e| e.to_string())?,
57      ImageSource::Memory(image_data) => {
58        image::load_from_memory(&image_data).map_err(|e| e.to_string())?
59      }
60      ImageSource::Url(_url) => {
61        #[cfg(not(feature = "http-blocking"))]
62        return Err("Need add feature = http-blocking".into());
63        #[cfg(feature = "http-blocking")]
64        {
65          let response = reqwest::blocking::get(&_url).map_err(|e| e.to_string())?;
66          let image_data = response.bytes().map_err(|e| e.to_string())?.to_vec();
67          image::load_from_memory(&image_data).map_err(|e| e.to_string())?
68        }
69      }
70      ImageSource::Database(_image_id) => {
71        // 根据图像ID从数据库检索图像数据
72        // 这里假设您有一个名为 load_from_database 的函数来执行此操作
73        // let image_data = load_from_database(image_id);
74        // image::load_from_memory(&image_data).expect("Failed to load image from database")
75        return Err("Database image loading is not implemented yet".into());
76      }
77      ImageSource::NetworkStream(bytes) => {
78        // 从网络流加载图像数据
79        let reader = std::io::Cursor::new(bytes);
80        Reader::new(reader)
81          .with_guessed_format().any()?
82          .decode()
83          .map_err(|e| e.to_string())?
84      }
85    })
86  }
87
88  /// 从指针获取数据
89  pub const unsafe fn from_raw_parts<T>(buf_ptr: *const T, len: usize) -> &'a [T] {
90    std::slice::from_raw_parts(buf_ptr, len)
91  }
92  /// 从指针获取数据
93  pub unsafe fn from_raw_parts_image<T>(buf_ptr: *const T, len: usize) -> Self {
94    Self::Memory(Self::from_raw_parts(buf_ptr as *const u8, len))
95  }
96  /// 从指针获取数据
97  pub unsafe fn from_raw_parts_reader<T>(
98    buf_ptr: *const T,
99    len: usize,
100  ) -> Result<Reader<Cursor<&'a [u8]>>> {
101    let x = Reader::new(std::io::Cursor::new(Self::from_raw_parts(
102      buf_ptr as *const u8,
103      len,
104    )))
105    .with_guessed_format().any()?;
106    Ok(x)
107  }
108  /// 从指针获取数据
109  #[cfg(feature = "base64")]
110  pub unsafe fn from_raw_parts_base64<T>(buf_ptr: *const T, len: usize) -> Result<String> {
111    let reader = Self::from_raw_parts_reader(buf_ptr, len)?;
112    let iformat = reader.format().res()?;
113    let image = reader.decode().map_err(|e| e.to_string())?;
114    Self::image_to_base64(&image, iformat)
115  }
116  /// 转成指针和长度
117  pub fn to_ptr(self) -> Result<(*const u8, usize)> {
118    let image = self.to_image()?;
119    Self::image_to_ptr(image)
120  }
121
122  /// 转数据
123  pub fn image_write_bytes(
124    image: &DynamicImage,
125    iformat: image::ImageFormat,
126  ) -> Result<Cursor<Vec<u8>>> {
127    // 创建一个内存缓冲区
128    let mut cursor = Cursor::new(Vec::new());
129    image
130      .write_to(&mut cursor, iformat)
131      .map_err(|e| e.to_string())?;
132    Ok(cursor)
133  }
134
135  /// 转Base64
136  #[cfg(feature = "base64")]
137  pub fn to_base64(self, iformat: ImageFormat) -> Result<String> {
138    let image = self.to_image()?;
139    Self::image_to_base64(&image, iformat)
140  }
141
142  /// 转base64
143  #[cfg(feature = "base64")]
144  pub fn image_to_base64(image: &DynamicImage, iformat: ImageFormat) -> Result<String> {
145    Ok(crate::algorithm::base64::encode(
146      Self::image_write_bytes(image, iformat)?.into_inner(),
147    ))
148  }
149
150  /// 转成指针和长度
151  pub fn image_to_ptr(image: DynamicImage) -> Result<(*const u8, usize)> {
152    // 获取图像尺寸
153    let (width, height) = image.dimensions();
154    // 获取图像颜色类型
155    let color_type = image.color();
156    // 获取图像像素数据的指针
157    // 根据颜色类型确定每个像素的大小
158    let (ptr, pixel_size) = match color_type {
159      // RGB 图像,每个像素需要3个字节
160      ColorType::Rgb8 => (image.into_rgb8().as_ptr(), 3),
161      // RGBA 图像,每个像素需要4个字节
162      ColorType::Rgba8 => (image.into_rgba8().as_ptr(), 4),
163      _ => return Err("ColorType未知类型".into()),
164    };
165    // 计算图像像素数据的总大小
166    let total_size = (width * height) as usize * pixel_size;
167    Ok((ptr, total_size))
168  }
169}