e_utils/images/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#![allow(deprecated)]
use std::io::Cursor;

use crate::{AnyRes, Result};
use image::io::Reader;
pub use image::{ColorType, DynamicImage, GenericImageView, ImageFormat};

/// #枚举图像数据的来源
/// # Example
/// ```rust
/// use e_utils::images::ImageSource;
/// fn test() -> Result<()> {
///   let file_image = ImageSource::File("D:\\1.jpeg".to_string()).to_image()?;
///   let (width, height) = file_image.dimensions();
///   println!("Image dimensions (from file): {} x {}", width, height);
///   let url_image = ImageSource::Url(
///     "http://q5.itc.cn/q_70/images03/20240222/d442108f65694b5081b0e793208a704c.jpeg".to_string(),
///   )
///   .to_image()?;
///   let (width, height) = file_image.dimensions();
///   println!("Image dimensions (from Url): {} x {}", width, height);
///   url_image.save("D:\\url.jpeg")?;
///   Ok(())
/// }
/// fn test2() -> Result<()>{
///   // 从内存中获取数据
///   let image = unsafe { ImageSource::from_raw_parts(pic_buf_ptr, (*size_returned) as usize) }
///     .to_image()
///     .to_tauri()?;
///   // 获取图片数据
///   let base64 = ImageSource::image_to_base64(&image);
///   let bytes = ImageSource::image_into_bytes(image.clone());
///   let (ptr, len) = ImageSource::image_to_ptr(image).to_tauri()?;
///   let image = unsafe { ImageSource::from_raw_parts(ptr, len) };
///   Ok(())
/// }
/// ```
#[derive(Debug)]
pub enum ImageSource<'a> {
  /// 从文件加载图像,传入文件路径
  File(String),
  /// 从内存加载图像,传入图像数据的字节向量
  Memory(&'a [u8]),
  /// 从URL加载图像,传入URL地址
  Url(String),
  /// 从数据库加载图像,传入图像ID(假设)
  Database(u64),
  /// 从网络流加载图像,传入字节数据流
  NetworkStream(Vec<u8>),
}

impl<'a> ImageSource<'a> {
  /// 输出图像
  pub fn to_image(self) -> Result<DynamicImage> {
    Ok(match self {
      ImageSource::File(file_path) => image::open(file_path).map_err(|e| e.to_string())?,
      ImageSource::Memory(image_data) => {
        image::load_from_memory(&image_data).map_err(|e| e.to_string())?
      }
      ImageSource::Url(_url) => {
        #[cfg(not(feature = "http-blocking"))]
        return Err("Need add feature = http-blocking".into());
        #[cfg(feature = "http-blocking")]
        {
          let response = reqwest::blocking::get(&_url).map_err(|e| e.to_string())?;
          let image_data = response.bytes().map_err(|e| e.to_string())?.to_vec();
          image::load_from_memory(&image_data).map_err(|e| e.to_string())?
        }
      }
      ImageSource::Database(_image_id) => {
        // 根据图像ID从数据库检索图像数据
        // 这里假设您有一个名为 load_from_database 的函数来执行此操作
        // let image_data = load_from_database(image_id);
        // image::load_from_memory(&image_data).expect("Failed to load image from database")
        return Err("Database image loading is not implemented yet".into());
      }
      ImageSource::NetworkStream(bytes) => {
        // 从网络流加载图像数据
        let reader = std::io::Cursor::new(bytes);
        Reader::new(reader)
          .with_guessed_format().any()?
          .decode()
          .map_err(|e| e.to_string())?
      }
    })
  }

  /// 从指针获取数据
  pub const unsafe fn from_raw_parts<T>(buf_ptr: *const T, len: usize) -> &'a [T] {
    std::slice::from_raw_parts(buf_ptr, len)
  }
  /// 从指针获取数据
  pub unsafe fn from_raw_parts_image<T>(buf_ptr: *const T, len: usize) -> Self {
    Self::Memory(Self::from_raw_parts(buf_ptr as *const u8, len))
  }
  /// 从指针获取数据
  pub unsafe fn from_raw_parts_reader<T>(
    buf_ptr: *const T,
    len: usize,
  ) -> Result<Reader<Cursor<&'a [u8]>>> {
    let x = Reader::new(std::io::Cursor::new(Self::from_raw_parts(
      buf_ptr as *const u8,
      len,
    )))
    .with_guessed_format().any()?;
    Ok(x)
  }
  /// 从指针获取数据
  #[cfg(feature = "base64")]
  pub unsafe fn from_raw_parts_base64<T>(buf_ptr: *const T, len: usize) -> Result<String> {
    let reader = Self::from_raw_parts_reader(buf_ptr, len)?;
    let iformat = reader.format().res()?;
    let image = reader.decode().map_err(|e| e.to_string())?;
    Self::image_to_base64(&image, iformat)
  }
  /// 转成指针和长度
  pub fn to_ptr(self) -> Result<(*const u8, usize)> {
    let image = self.to_image()?;
    Self::image_to_ptr(image)
  }

  /// 转数据
  pub fn image_write_bytes(
    image: &DynamicImage,
    iformat: image::ImageFormat,
  ) -> Result<Cursor<Vec<u8>>> {
    // 创建一个内存缓冲区
    let mut cursor = Cursor::new(Vec::new());
    image
      .write_to(&mut cursor, iformat)
      .map_err(|e| e.to_string())?;
    Ok(cursor)
  }

  /// 转Base64
  #[cfg(feature = "base64")]
  pub fn to_base64(self, iformat: ImageFormat) -> Result<String> {
    let image = self.to_image()?;
    Self::image_to_base64(&image, iformat)
  }

  /// 转base64
  #[cfg(feature = "base64")]
  pub fn image_to_base64(image: &DynamicImage, iformat: ImageFormat) -> Result<String> {
    Ok(crate::algorithm::base64::encode(
      Self::image_write_bytes(image, iformat)?.into_inner(),
    ))
  }

  /// 转成指针和长度
  pub fn image_to_ptr(image: DynamicImage) -> Result<(*const u8, usize)> {
    // 获取图像尺寸
    let (width, height) = image.dimensions();
    // 获取图像颜色类型
    let color_type = image.color();
    // 获取图像像素数据的指针
    // 根据颜色类型确定每个像素的大小
    let (ptr, pixel_size) = match color_type {
      // RGB 图像,每个像素需要3个字节
      ColorType::Rgb8 => (image.into_rgb8().as_ptr(), 3),
      // RGBA 图像,每个像素需要4个字节
      ColorType::Rgba8 => (image.into_rgba8().as_ptr(), 4),
      _ => return Err("ColorType未知类型".into()),
    };
    // 计算图像像素数据的总大小
    let total_size = (width * height) as usize * pixel_size;
    Ok((ptr, total_size))
  }
}