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#[derive(Debug)]
39pub enum ImageSource<'a> {
40 File(String),
42 Memory(&'a [u8]),
44 Url(String),
46 Database(u64),
48 NetworkStream(Vec<u8>),
50}
51
52impl<'a> ImageSource<'a> {
53 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 return Err("Database image loading is not implemented yet".into());
76 }
77 ImageSource::NetworkStream(bytes) => {
78 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 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 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 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 #[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 pub fn to_ptr(self) -> Result<(*const u8, usize)> {
118 let image = self.to_image()?;
119 Self::image_to_ptr(image)
120 }
121
122 pub fn image_write_bytes(
124 image: &DynamicImage,
125 iformat: image::ImageFormat,
126 ) -> Result<Cursor<Vec<u8>>> {
127 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 #[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 #[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 pub fn image_to_ptr(image: DynamicImage) -> Result<(*const u8, usize)> {
152 let (width, height) = image.dimensions();
154 let color_type = image.color();
156 let (ptr, pixel_size) = match color_type {
159 ColorType::Rgb8 => (image.into_rgb8().as_ptr(), 3),
161 ColorType::Rgba8 => (image.into_rgba8().as_ptr(), 4),
163 _ => return Err("ColorType未知类型".into()),
164 };
165 let total_size = (width * height) as usize * pixel_size;
167 Ok((ptr, total_size))
168 }
169}