1use crate::error::DocxError;
2use image::{GenericImageView, load_from_memory};
3use std::fs::File;
4use std::io::Read;
5use uuid::Uuid;
6
7static IMAGE_WIDTH: f32 = 6.09;
8static IMAGE_HEIGHT: f32 = 5.9;
9pub static DOCX_EMU: f32 = 360000.0;
11static DPI: f64 = 96f64;
13static EMU: f64 = 914400f64;
15
16pub struct DocxImage {
18 pub image_path: String,
20 pub image_data: Vec<u8>,
22 pub relation_id: String,
24 pub width: u64,
26 pub height: u64,
28}
29
30impl DocxImage {
31 pub fn new(image_path: &str) -> Result<Self, DocxError> {
34 let mut file = File::open(image_path)?;
36 let mut image_data = Vec::new();
37 file.read_to_end(&mut image_data)?;
38 let (width_emu, height_emu) = get_image_size(&image_data)?;
39 Self::new_size_emu(image_path, image_data, width_emu, height_emu)
40 }
41 pub fn new_size_emu(
46 image_path: &str,
47 image_data: Vec<u8>,
48 width: u64,
49 height: u64,
50 ) -> Result<Self, DocxError> {
51 DocxImage::new_image_data_size(image_path, image_data, width, height)
52 }
53
54 pub fn new_size(image_path: &str, width: u64, height: u64) -> Result<Self, DocxError> {
59 let mut file = File::open(image_path)?;
61 let mut image_data = Vec::new();
62 file.read_to_end(&mut image_data)?;
63 DocxImage::new_image_data_size(image_path, image_data, width, height)
64 }
65
66 pub fn new_image_data(image_url: &str, image_data: Vec<u8>) -> Result<Self, DocxError> {
70 let (width_emu, height_emu) = get_image_size(&image_data)?;
71 DocxImage::new_image_data_size(image_url, image_data, width_emu, height_emu)
72 }
73
74 pub fn new_image_data_size(
80 image_url: &str,
81 image_data: Vec<u8>,
82 width: u64,
83 height: u64,
84 ) -> Result<Self, DocxError> {
85 Ok(DocxImage {
86 image_path: image_url.to_string(),
87 relation_id: format!("rId{}", Uuid::new_v4().simple()),
88 width,
89 height,
90 image_data,
91 })
92 }
93}
94
95fn get_image_size(image_data: &[u8]) -> Result<(u64, u64), DocxError> {
96 let img = load_from_memory(&image_data)?;
97 let (width_px, height_px) = img.dimensions();
98 let width_emu = (width_px as f64 * EMU / &DPI) as u64;
99 let height_emu = (height_px as f64 * EMU / &DPI) as u64;
100 Ok((width_emu, height_emu))
101}