image_renderer/
image.rs

1//! Image 类型模块
2//!
3//! 提供独立于 Surface 的图片对象,支持编解码
4
5use crate::error::{ImageError, ImageResult};
6use crate::surface::Surface;
7use image::Rgba;
8
9/// 图片格式枚举
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ImageFormat {
12    /// PNG 格式
13    PNG,
14    /// JPEG 格式
15    JPEG,
16    /// WEBP 格式(暂未实现)
17    WEBP,
18}
19
20/// Image 类型
21///
22/// 独立的图片对象,提供编解码功能
23#[derive(Clone)]
24pub struct Image {
25    /// 内部 Surface
26    surface: Surface,
27}
28
29impl Image {
30    /// 从字节数据解码图片
31    ///
32    /// # 参数
33    ///
34    /// * `data` - 图片的字节数据
35    ///
36    /// # 示例
37    ///
38    /// ```no_run
39    /// use image_renderer::Image;
40    ///
41    /// let bytes = std::fs::read("image.png").unwrap();
42    /// let image = Image::from_encoded(&bytes).unwrap();
43    /// ```
44    pub fn from_encoded(data: &[u8]) -> ImageResult<Self> {
45        let surface = Surface::from_bytes(data)?;
46        Ok(Image { surface })
47    }
48
49    /// 从 Surface 创建 Image
50    pub fn from_surface(surface: Surface) -> Self {
51        Image { surface }
52    }
53
54    /// 编码图片为指定格式
55    ///
56    /// # 参数
57    ///
58    /// * `format` - 目标图片格式
59    /// * `quality` - 质量参数(仅对 JPEG 有效,范围 0-100)
60    ///
61    /// # 示例
62    ///
63    /// ```no_run
64    /// use image_renderer::{Image, ImageFormat};
65    ///
66    /// let image = Image::from_encoded(&bytes).unwrap();
67    /// let png_bytes = image.encode(ImageFormat::PNG, None).unwrap();
68    /// let jpeg_bytes = image.encode(ImageFormat::JPEG, Some(90)).unwrap();
69    /// ```
70    pub fn encode(&self, format: ImageFormat, quality: Option<u8>) -> ImageResult<Vec<u8>> {
71        match format {
72            ImageFormat::PNG => self.surface.to_png_bytes(),
73            ImageFormat::JPEG => {
74                let quality = quality.unwrap_or(90);
75                self.surface.to_jpeg_bytes(quality)
76            }
77            ImageFormat::WEBP => Err(ImageError::ProcessingError(
78                "WEBP format is not yet supported".to_string(),
79            )),
80        }
81    }
82
83    /// 获取图片宽度
84    pub fn width(&self) -> u32 {
85        self.surface.width()
86    }
87
88    /// 获取图片高度
89    pub fn height(&self) -> u32 {
90        self.surface.height()
91    }
92
93    /// 获取图片尺寸
94    pub fn dimensions(&self) -> (u32, u32) {
95        self.surface.dimensions()
96    }
97
98    /// 获取内部 Surface 的引用
99    pub fn surface(&self) -> &Surface {
100        &self.surface
101    }
102
103    /// 获取内部 Surface 的可变引用
104    pub fn surface_mut(&mut self) -> &mut Surface {
105        &mut self.surface
106    }
107
108    /// 转换为 Surface
109    pub fn into_surface(self) -> Surface {
110        self.surface
111    }
112
113    /// 获取指定位置的像素
114    pub fn get_pixel(&self, x: u32, y: u32) -> Option<Rgba<u8>> {
115        self.surface.get_pixel(x, y)
116    }
117
118    /// 裁剪图片
119    pub fn crop(&self, x: u32, y: u32, width: u32, height: u32) -> ImageResult<Self> {
120        let cropped = self.surface.crop(x, y, width, height)?;
121        Ok(Image::from_surface(cropped))
122    }
123
124    /// 调整图片大小
125    pub fn resize(&self, width: u32, height: u32) -> ImageResult<Self> {
126        let resized = self.surface.resize(width, height)?;
127        Ok(Image::from_surface(resized))
128    }
129
130    /// 获取像素数据视图
131    ///
132    /// 返回一个 Pixmap,提供对图片像素数据的只读访问
133    ///
134    /// # 示例
135    ///
136    /// ```no_run
137    /// use image_renderer::{Image, IPoint};
138    ///
139    /// let image = Image::from_encoded(&bytes).unwrap();
140    /// let pixmap = image.peek_pixels();
141    /// let color = pixmap.get_color(IPoint::new(10, 10));
142    /// ```
143    pub fn peek_pixels(&self) -> crate::pixmap::Pixmap<'_> {
144        crate::pixmap::Pixmap::from_surface(&self.surface)
145    }
146}
147
148impl From<Surface> for Image {
149    fn from(surface: Surface) -> Self {
150        Image::from_surface(surface)
151    }
152}
153
154impl From<Image> for Surface {
155    fn from(image: Image) -> Self {
156        image.into_surface()
157    }
158}