umya_spreadsheet/structs/
image.rs1use crate::structs::drawing::spreadsheet::MarkerType;
2use crate::structs::drawing::spreadsheet::OneCellAnchor;
3use crate::structs::drawing::spreadsheet::Picture;
4use crate::structs::drawing::spreadsheet::TwoCellAnchor;
5use crate::structs::drawing::FillRectangle;
6use crate::structs::drawing::PresetGeometry;
7use crate::structs::drawing::Stretch;
8use crate::structs::MediaObject;
9use crate::traits::AdjustmentCoordinate;
10use base64::{engine::general_purpose::STANDARD, Engine as _};
11use quick_xml::Writer;
12use std::fs;
13use std::fs::File;
14use std::io::BufReader;
15use std::io::Cursor;
16use std::io::Read;
17
18lazy_static! {
19 static ref EMPTY_VEC: Vec<u8> = Vec::new();
20}
21
22#[derive(Clone, Default, Debug)]
23pub struct Image {
24 two_cell_anchor: Option<Box<TwoCellAnchor>>,
25 one_cell_anchor: Option<Box<OneCellAnchor>>,
26}
27impl Image {
68 #[inline]
69 pub fn get_two_cell_anchor(&self) -> Option<&TwoCellAnchor> {
70 self.two_cell_anchor.as_deref()
71 }
72
73 #[inline]
74 pub fn get_two_cell_anchor_mut(&mut self) -> Option<&mut TwoCellAnchor> {
75 self.two_cell_anchor.as_deref_mut()
76 }
77
78 #[inline]
79 pub fn set_two_cell_anchor(&mut self, value: TwoCellAnchor) -> &mut Self {
80 self.two_cell_anchor = Some(Box::new(value));
81 self
82 }
83
84 #[inline]
85 pub fn remove_two_cell_anchor(&mut self) -> &mut Self {
86 self.two_cell_anchor = None;
87 self
88 }
89
90 #[inline]
91 pub fn get_one_cell_anchor(&self) -> Option<&OneCellAnchor> {
92 self.one_cell_anchor.as_deref()
93 }
94
95 #[inline]
96 pub fn get_one_cell_anchor_mut(&mut self) -> Option<&mut OneCellAnchor> {
97 self.one_cell_anchor.as_deref_mut()
98 }
99
100 #[inline]
101 pub fn set_one_cell_anchor(&mut self, value: OneCellAnchor) -> &mut Self {
102 self.one_cell_anchor = Some(Box::new(value));
103 self
104 }
105
106 #[inline]
107 pub fn remove_one_cell_anchor(&mut self) -> &mut Self {
108 self.one_cell_anchor = None;
109 self
110 }
111
112 pub fn new_image(&mut self, path: &str, marker: MarkerType) {
113 let path = std::path::Path::new(path);
114
115 let size = imagesize::size(path).unwrap();
116 let image_name = path.file_name().unwrap().to_str().unwrap();
117 let mut buf = Vec::new();
118
119 let file = File::open(path).unwrap();
120 BufReader::new(file).read_to_end(&mut buf).unwrap();
121
122 self.new_image_with_dimensions(
123 size.height as u32,
124 size.width as u32,
125 image_name,
126 buf,
127 marker,
128 )
129 }
130
131 pub fn new_image_with_dimensions<B: Into<Vec<u8>>>(
132 &mut self,
133 height: u32,
134 width: u32,
135 image_name: &str,
136 bytes: B,
137 marker: MarkerType,
138 ) {
139 let mut picture = Picture::default();
140 picture
142 .get_blip_fill_mut()
143 .get_blip_mut()
144 .set_cstate("print")
145 .get_image_mut()
146 .set_image_name(image_name)
147 .set_image_data(bytes.into());
148
149 picture
151 .get_non_visual_picture_properties_mut()
152 .get_non_visual_drawing_properties_mut()
153 .set_name(image_name);
154
155 picture
157 .get_non_visual_picture_properties_mut()
158 .get_non_visual_picture_drawing_properties_mut()
159 .set_prefer_relative_resize(false);
160
161 let fill_rectangle = FillRectangle::default();
163 let mut stretch = Stretch::default();
164 stretch.set_fill_rectangle(fill_rectangle);
165 picture.get_blip_fill_mut().set_stretch(stretch);
166
167 picture
169 .get_shape_properties_mut()
170 .get_geometry_mut()
171 .set_geometry(PresetGeometry::GEOMETRY_RECT);
172
173 let mut one_cell_anchor = OneCellAnchor::default();
174 one_cell_anchor.set_from_marker(marker);
175 one_cell_anchor
176 .get_extent_mut()
177 .set_cy(height as i64 * 9525);
178 one_cell_anchor.get_extent_mut().set_cx(width as i64 * 9525);
179 one_cell_anchor.set_picture(picture);
180 self.set_one_cell_anchor(one_cell_anchor);
181 }
182
183 #[inline]
184 pub fn change_image(&mut self, path: &str) {
185 let marker = self.get_from_marker_type().clone();
186 self.remove_two_cell_anchor();
187 self.remove_one_cell_anchor();
188 self.new_image(path, marker);
189 }
190
191 #[inline]
192 pub fn download_image(&self, path: &str) {
193 fs::write(path, self.get_image_data()).unwrap();
194 }
195
196 #[inline]
197 pub fn has_image(&self) -> bool {
198 !self.get_media_object().is_empty()
199 }
200
201 #[inline]
202 pub fn get_image_name(&self) -> &str {
203 match self.get_media_object().first() {
204 Some(v) => v.get_image_name(),
205 None => "",
206 }
207 }
208
209 #[inline]
210 pub fn get_image_data(&self) -> &[u8] {
211 match self.get_media_object().first() {
212 Some(v) => v.get_image_data(),
213 None => &EMPTY_VEC,
214 }
215 }
216
217 #[inline]
218 pub fn get_image_data_base64(&self) -> String {
219 STANDARD.encode(self.get_image_data())
220 }
221
222 #[inline]
223 pub fn get_coordinate(&self) -> String {
224 self.get_from_marker_type().get_coordinate()
225 }
226
227 #[inline]
228 pub fn get_col(&self) -> &u32 {
229 self.get_from_marker_type().get_col()
230 }
231
232 #[inline]
233 pub fn get_row(&self) -> &u32 {
234 self.get_from_marker_type().get_row()
235 }
236
237 #[inline]
238 pub fn get_from_marker_type(&self) -> &MarkerType {
239 if let Some(anchor) = self.get_two_cell_anchor() {
240 return anchor.get_from_marker();
241 }
242 if let Some(anchor) = self.get_one_cell_anchor() {
243 return anchor.get_from_marker();
244 }
245 panic!("Not Found MediaObject");
246 }
247
248 #[inline]
249 pub fn get_to_marker_type(&self) -> Option<&MarkerType> {
250 self.get_two_cell_anchor()
251 .as_ref()
252 .map(|anchor| anchor.get_to_marker())
253 }
254
255 pub(crate) fn get_media_object(&self) -> Vec<&MediaObject> {
256 let mut result: Vec<&MediaObject> = Vec::new();
257 if let Some(anchor) = self.get_two_cell_anchor() {
258 if let Some(v) = anchor.get_picture() {
259 result.push(v.get_blip_fill().get_blip().get_image());
260 }
261 if let Some(v) = anchor.get_shape() {
262 if let Some(bf) = v.get_shape_properties().get_blip_fill() {
263 result.push(bf.get_blip().get_image());
264 }
265 }
266 if let Some(v) = anchor.get_connection_shape() {
267 if let Some(bf) = v.get_shape_properties().get_blip_fill() {
268 result.push(bf.get_blip().get_image());
269 }
270 }
271 if let Some(v) = anchor.get_group_shape() {
272 for pic in v.get_picture_collection() {
273 result.push(pic.get_blip_fill().get_blip().get_image());
274 }
275 for shp in v.get_shape_collection() {
276 if let Some(bf) = shp.get_shape_properties().get_blip_fill() {
277 result.push(bf.get_blip().get_image());
278 }
279 }
280 }
281 }
282 if let Some(anchor) = self.get_one_cell_anchor() {
283 if let Some(v) = anchor.get_picture() {
284 result.push(v.get_blip_fill().get_blip().get_image());
285 }
286 if let Some(v) = anchor.get_shape() {
287 if let Some(bf) = v.get_shape_properties().get_blip_fill() {
288 result.push(bf.get_blip().get_image());
289 }
290 }
291 if let Some(v) = anchor.get_group_shape() {
292 for pic in v.get_picture_collection() {
293 result.push(pic.get_blip_fill().get_blip().get_image());
294 }
295 for shp in v.get_shape_collection() {
296 if let Some(bf) = shp.get_shape_properties().get_blip_fill() {
297 result.push(bf.get_blip().get_image());
298 }
299 }
300 }
301 }
302 result
303 }
304
305 #[inline]
306 pub(crate) fn write_to(
307 &self,
308 writer: &mut Writer<Cursor<Vec<u8>>>,
309 rel_list: &mut Vec<(String, String)>,
310 ) {
311 if let Some(anchor) = self.get_two_cell_anchor() {
312 anchor.write_to(writer, rel_list, &0);
313 }
314 if let Some(anchor) = self.get_one_cell_anchor() {
315 anchor.write_to(writer, rel_list);
316 }
317 }
318}
319impl AdjustmentCoordinate for Image {
320 #[inline]
321 fn adjustment_insert_coordinate(
322 &mut self,
323 root_col_num: &u32,
324 offset_col_num: &u32,
325 root_row_num: &u32,
326 offset_row_num: &u32,
327 ) {
328 match self.one_cell_anchor.as_mut() {
330 Some(anchor) => {
331 anchor.adjustment_insert_coordinate(
332 root_col_num,
333 offset_col_num,
334 root_row_num,
335 offset_row_num,
336 );
337 }
338 None => {}
339 }
340
341 match self.two_cell_anchor.as_mut() {
343 Some(anchor) => {
344 anchor.adjustment_insert_coordinate(
345 root_col_num,
346 offset_col_num,
347 root_row_num,
348 offset_row_num,
349 );
350 }
351 None => {}
352 }
353 }
354
355 #[inline]
356 fn adjustment_remove_coordinate(
357 &mut self,
358 root_col_num: &u32,
359 offset_col_num: &u32,
360 root_row_num: &u32,
361 offset_row_num: &u32,
362 ) {
363 match self.one_cell_anchor.as_mut() {
365 Some(anchor) => {
366 anchor.adjustment_remove_coordinate(
367 root_col_num,
368 offset_col_num,
369 root_row_num,
370 offset_row_num,
371 );
372 }
373 None => {}
374 }
375
376 match self.two_cell_anchor.as_mut() {
378 Some(anchor) => {
379 anchor.adjustment_remove_coordinate(
380 root_col_num,
381 offset_col_num,
382 root_row_num,
383 offset_row_num,
384 );
385 }
386 None => {}
387 }
388 }
389
390 #[inline]
391 fn is_remove_coordinate(
392 &self,
393 root_col_num: &u32,
394 offset_col_num: &u32,
395 root_row_num: &u32,
396 offset_row_num: &u32,
397 ) -> bool {
398 match self.one_cell_anchor.as_ref() {
399 Some(anchor) => {
400 return anchor.is_remove_coordinate(
401 root_col_num,
402 offset_col_num,
403 root_row_num,
404 offset_row_num,
405 );
406 }
407 None => {}
408 }
409 match self.two_cell_anchor.as_ref() {
410 Some(anchor) => {
411 return anchor.is_remove_coordinate(
412 root_col_num,
413 offset_col_num,
414 root_row_num,
415 offset_row_num,
416 );
417 }
418 None => {}
419 }
420 false
421 }
422}