diff --git a/docx-core/Cargo.toml b/docx-core/Cargo.toml index 564e94c..20675e0 100644 --- a/docx-core/Cargo.toml +++ b/docx-core/Cargo.toml @@ -18,7 +18,8 @@ name = "docx_rs" path = "src/lib.rs" [features] -wasm = ["wasm-bindgen", "ts-rs"] +default = ["image"] +wasm = ["wasm-bindgen", "ts-rs", "image"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -29,7 +30,7 @@ zip = { version = "0.6.3", default-features = false, features = ["deflate"] } serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0" } base64 = "0.13.1" -image = { version = "0.24.4", default-features = false, features=["gif", "jpeg", "png", "bmp", "tiff"] } +image = { version = "0.24.4", default-features = false, features=["gif", "jpeg", "png", "bmp", "tiff"], optional = true } wasm-bindgen = { version = "0.2.78", optional = true } ts-rs = { version = "6.1", optional = true } diff --git a/docx-core/src/documents/elements/drawing.rs b/docx-core/src/documents/elements/drawing.rs index 69bac1b..2af72c2 100644 --- a/docx-core/src/documents/elements/drawing.rs +++ b/docx-core/src/documents/elements/drawing.rs @@ -163,12 +163,8 @@ mod tests { #[test] fn test_drawing_build_with_pic() { - use std::io::Read; - - let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap(); - let mut buf = Vec::new(); - let _ = img.read_to_end(&mut buf).unwrap(); - let d = Drawing::new().pic(Pic::new(&buf)).build(); + let pic = Pic::new_with_dimensions(Vec::new(), 320, 240); + let d = Drawing::new().pic(pic).build(); assert_eq!( str::from_utf8(&d).unwrap(), r#" @@ -212,12 +208,8 @@ mod tests { #[test] fn test_drawing_build_with_pic_overlap() { - use std::io::Read; - - let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap(); - let mut buf = Vec::new(); - let _ = img.read_to_end(&mut buf).unwrap(); - let d = Drawing::new().pic(Pic::new(&buf).overlapping()).build(); + let pic = Pic::new_with_dimensions(Vec::new(), 320, 240).overlapping(); + let d = Drawing::new().pic(pic).build(); assert_eq!( str::from_utf8(&d).unwrap(), r#" @@ -262,12 +254,7 @@ mod tests { #[test] fn test_drawing_build_with_pic_align_right() { - use std::io::Read; - - let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap(); - let mut buf = Vec::new(); - let _ = img.read_to_end(&mut buf).unwrap(); - let mut pic = Pic::new(&buf).floating(); + let mut pic = Pic::new_with_dimensions(Vec::new(), 320, 240).floating(); pic = pic.relative_from_h(RelativeFromHType::Column); pic = pic.relative_from_v(RelativeFromVType::Paragraph); pic = pic.position_h(DrawingPosition::Align(PicAlign::Right)); @@ -323,12 +310,7 @@ mod tests { #[test] fn test_issue686() { - use std::io::Read; - - let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap(); - let mut buf = Vec::new(); - let _ = img.read_to_end(&mut buf).unwrap(); - let pic = Pic::new(&buf) + let pic = Pic::new_with_dimensions(Vec::new(), 320, 240) .size(320 * 9525, 240 * 9525) .floating() .offset_x(300 * 9525) diff --git a/docx-core/src/documents/elements/pic.rs b/docx-core/src/documents/elements/pic.rs index 18b310a..5a331e5 100644 --- a/docx-core/src/documents/elements/pic.rs +++ b/docx-core/src/documents/elements/pic.rs @@ -1,4 +1,3 @@ -use image::*; use serde::Serialize; use crate::documents::*; @@ -50,18 +49,28 @@ pub struct Pic { } impl Pic { + #[cfg(feature = "image")] + /// Make a `Pic`. + /// + /// Converts the passed image to PNG internally and computes its size. pub fn new(buf: &[u8]) -> Pic { - let id = create_pic_rid(generate_pic_id()); - let dimg = image::load_from_memory(buf).expect("Should load image from memory."); - let size = dimg.dimensions(); - let mut image = std::io::Cursor::new(vec![]); - // For now only png supported - dimg.write_to(&mut image, ImageFormat::Png) + let img = ::image::load_from_memory(buf).expect("Should load image from memory."); + let (w, h) = ::image::GenericImageView::dimensions(&img); + let mut buf = std::io::Cursor::new(vec![]); + img.write_to(&mut buf, ::image::ImageFormat::Png) .expect("Unable to write dynamic image"); + Self::new_with_dimensions(buf.into_inner(), w, h) + } + + /// Make a `Pic` element. For now only PNG is supported. + /// + /// Use [Pic::new] method, to call `image` crate do conversion for you. + pub fn new_with_dimensions(buffer: Vec, width_px: u32, height_px: u32) -> Pic { + let id = create_pic_rid(generate_pic_id()); Self { id, - image: image.into_inner(), - size: (from_px(size.0), from_px(size.1)), + image: buffer, + size: (from_px(width_px), from_px(height_px)), position_type: DrawingPositionType::Inline, simple_pos: false, simple_pos_x: 0, @@ -236,12 +245,7 @@ mod tests { #[test] fn test_pic_build() { - use std::io::Read; - - let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap(); - let mut buf = Vec::new(); - let _ = img.read_to_end(&mut buf).unwrap(); - let b = Pic::new(&buf).build(); + let b = Pic::new_with_dimensions(Vec::new(), 320, 240).build(); assert_eq!( str::from_utf8(&b).unwrap(), r#" diff --git a/docx-core/src/documents/mod.rs b/docx-core/src/documents/mod.rs index fba1c3c..5d86bba 100644 --- a/docx-core/src/documents/mod.rs +++ b/docx-core/src/documents/mod.rs @@ -43,7 +43,6 @@ mod xml_docx; pub(crate) use build_xml::BuildXML; pub(crate) use history_id::HistoryId; pub(crate) use hyperlink_id::*; -use image::ImageFormat; pub(crate) use paragraph_id::*; pub(crate) use paragraph_property_change_id::ParagraphPropertyChangeId; pub(crate) use pic_id::*; @@ -246,15 +245,22 @@ impl Docx { path: impl Into, buf: Vec, ) -> Self { + #[cfg(feature = "image")] if let Ok(dimg) = image::load_from_memory(&buf) { let mut png = std::io::Cursor::new(vec![]); // For now only png supported - dimg.write_to(&mut png, ImageFormat::Png) + dimg.write_to(&mut png, image::ImageFormat::Png) .expect("Unable to write dynamic image"); self.images .push((id.into(), path.into(), Image(buf), Png(png.into_inner()))); } + #[cfg(not(feature = "image"))] + // without 'image' crate we can only test for PNG file signature + if buf.starts_with(&[137, 80, 78, 71, 13, 10, 26, 10]) { + self.images + .push((id.into(), path.into(), Image(buf.clone()), Png(buf))); + } self }