1use crate::error::{ImageError, ImageResult};
6use crate::surface::Surface;
7use image::Rgba;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ImageFormat {
12 PNG,
14 JPEG,
16 WEBP,
18}
19
20#[derive(Clone)]
24pub struct Image {
25 surface: Surface,
27}
28
29impl Image {
30 pub fn from_encoded(data: &[u8]) -> ImageResult<Self> {
45 let surface = Surface::from_bytes(data)?;
46 Ok(Image { surface })
47 }
48
49 pub fn from_surface(surface: Surface) -> Self {
51 Image { surface }
52 }
53
54 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 pub fn width(&self) -> u32 {
85 self.surface.width()
86 }
87
88 pub fn height(&self) -> u32 {
90 self.surface.height()
91 }
92
93 pub fn dimensions(&self) -> (u32, u32) {
95 self.surface.dimensions()
96 }
97
98 pub fn surface(&self) -> &Surface {
100 &self.surface
101 }
102
103 pub fn surface_mut(&mut self) -> &mut Surface {
105 &mut self.surface
106 }
107
108 pub fn into_surface(self) -> Surface {
110 self.surface
111 }
112
113 pub fn get_pixel(&self, x: u32, y: u32) -> Option<Rgba<u8>> {
115 self.surface.get_pixel(x, y)
116 }
117
118 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 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 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}