easyofd_core/model/
image_object.rs1use crate::model::image_format::ImageFormat;
4
5#[derive(Debug, Clone)]
7pub struct ImageObject {
8 pub x: f64,
10 pub y: f64,
12 pub width: f64,
14 pub height: f64,
16 pub data: Vec<u8>,
18 pub format: ImageFormat,
20 pub res_name: Option<String>,
25}
26
27impl ImageObject {
28 #[must_use]
30 pub fn new(
31 x: f64,
32 y: f64,
33 width: f64,
34 height: f64,
35 data: Vec<u8>,
36 format: ImageFormat,
37 ) -> Self {
38 Self {
39 x,
40 y,
41 width,
42 height,
43 data,
44 format,
45 res_name: None,
46 }
47 }
48
49 #[must_use]
51 pub fn with_res_name(mut self, res_name: impl Into<String>) -> Self {
52 self.res_name = Some(res_name.into());
53 self
54 }
55
56 #[must_use]
58 pub fn jpeg(x: f64, y: f64, width: f64, height: f64, data: Vec<u8>) -> Self {
59 Self::new(x, y, width, height, data, ImageFormat::Jpeg)
60 }
61
62 #[must_use]
64 pub fn png(x: f64, y: f64, width: f64, height: f64, data: Vec<u8>) -> Self {
65 Self::new(x, y, width, height, data, ImageFormat::Png)
66 }
67
68 pub fn from_file(
78 x: f64,
79 y: f64,
80 width: f64,
81 height: f64,
82 path: impl AsRef<std::path::Path>,
83 ) -> crate::OfdResult<Self> {
84 let data = std::fs::read(path.as_ref()).map_err(crate::OfdError::Io)?;
85 let format = detect_image_format(path.as_ref(), &data);
86 Ok(Self::new(x, y, width, height, data, format))
87 }
88}
89
90fn detect_image_format(path: &std::path::Path, data: &[u8]) -> ImageFormat {
92 if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
94 match ext.to_lowercase().as_str() {
95 "jpg" | "jpeg" => return ImageFormat::Jpeg,
96 "png" => return ImageFormat::Png,
97 "bmp" => return ImageFormat::Bmp,
98 "tiff" | "tif" => return ImageFormat::Tiff,
99 _ => {}
100 }
101 }
102 if data.len() >= 2 && data[0] == 0xFF && data[1] == 0xD8 {
104 return ImageFormat::Jpeg;
105 }
106 if data.len() >= 4 && data[0] == 0x89 && data[1] == b'P' && data[2] == b'N' && data[3] == b'G' {
107 return ImageFormat::Png;
108 }
109 if data.len() >= 2 && data[0] == b'B' && data[1] == b'M' {
110 return ImageFormat::Bmp;
111 }
112 if data.len() >= 4
113 && ((data[0] == b'I' && data[1] == b'I') || (data[0] == b'M' && data[1] == b'M'))
114 && data[2] == 0x00
115 && data[3] == 0x2A
116 {
117 return ImageFormat::Tiff;
118 }
119 ImageFormat::Jpeg
121}