bokuweb / docx-rs

:memo: A .docx file writer with Rust/WebAssembly.
https://bokuweb.github.io/docx-rs/
MIT License
321 stars 56 forks source link

Picture embedded as PNG #701

Open bublikOff opened 3 months ago

bublikOff commented 3 months ago

Adding JPG picture to a document will result that it will be embedded as PNG. Is this a DOCX spec? or ... PNG file dramatically increases resulting docx file size

arifd commented 1 week ago

This is a mistake of the public API of docx-rs IMO. However, luckily you can get around it because the author left all the fields of Pic public, so you can construct it yourself with this code: (it will also dramatically improve the speed if you embed images):

use docx_rs::{DrawingPosition, DrawingPositionType, Pic, RelativeFromHType, RelativeFromVType};

pub fn pic(image: Vec<u8>, w_px: u32, h_px: u32) -> Pic {
    Pic {
        id: create_pic_rid(generate_pic_id()),
        image,
        size: (px_to_emu(w_px), px_to_emu(h_px)),
        position_type: DrawingPositionType::Inline,
        simple_pos: false,
        simple_pos_x: 0,
        simple_pos_y: 0,
        layout_in_cell: false,
        relative_height: 190500,
        allow_overlap: false,
        position_v: DrawingPosition::Offset(0),
        position_h: DrawingPosition::Offset(0),
        relative_from_h: RelativeFromHType::default(),
        relative_from_v: RelativeFromVType::default(),
        dist_t: 0,
        dist_b: 0,
        dist_l: 0,
        dist_r: 0,
        rot: 0,
    }
}

fn px_to_emu(px: u32) -> u32 {
    px * 9525
}

fn generate_pic_id() -> usize {
    use std::sync::atomic::{AtomicUsize, Ordering};
    static PIC_ID: AtomicUsize = AtomicUsize::new(1);
    PIC_ID.fetch_add(1, Ordering::Relaxed)
}

fn create_pic_rid(id: usize) -> String {
    format!("rIdImage{}", id)
}