docx
docx copied to clipboard
Allow to specify image fileName and emu dimensions
- allowing to specify the
fileNamewould help reducing the document size if the same image is included several times - allowing to specify the
transformation.emusseparately would allow to better set the image dimensions irrespective of the pixels.
currently, I need to hack it like this:
const drawing = new Drawing(imageData, { floating: false });
// hack to get document properties to set alt text
if (node.title || node.alt) {
const docProps = findXMLComponent(drawing, 'wp:inline/wp:docPr/_attr');
if (docProps && docProps.root) {
docProps.root.name = title || '';
docProps.root.descr = alt;
}
}
// create picture
const pic = new ImageRun({
data: data.buffer,
transformation: data.dimensions,
});
// replace drawing with custom filename and emu dimensions
const oldDrawing = findXMLComponent(pic, 'w:drawing');
const idx = pic.root.indexOf(oldDrawing);
if (idx >= 0) {
pic.root.splice(idx, 1);
}
pic.root.push(drawing);
pic.key = key;
pic.imageData = imageData;
allowing to specify the fileName would help reducing the document size if the same image is included several times
This one is done now!
allowing to specify the transformation.emus separately would allow to better set the image dimensions irrespective of the pixels.
Hmm not so sure, emu is is not as intuitive, and is just a scale factor of 9525, so maybe it isn't worth the effort
Can raise again if people have interest
thank you.
Hmm not so sure, emu is is not as intuitive, and is just a scale factor of 9525, so maybe it isn't worth the effort
but you are already using emu for the floating offsets.
The problem I found is, that if I want to keep the information about the original dimensions of the image, but scale it differently, eg restricting the width/height of an image inside a table, I need to set the emus.
eg:
let x = data.dimensions.width * 9525;
let y = data.dimensions.height * 9525;
const limits = ctx.tableAlign ? LIMITS_TABLE : LIMITS;
if (x > limits.width) {
y = Math.round((limits.width * y) / x);
x = limits.width;
}
if (y > limits.height) {
x = Math.round((limits.height * x) / y);
y = limits.height;
}
const imageData = {
stream: data.buffer,
fileName: data.key,
transformation: {
pixels: {
x: Math.round(data.dimensions.width),
y: Math.round(data.dimensions.height),
},
emus: {
x,
y,
},
},
};
and then create the Drawing and replace the image as described above.
Ok, I see the issue, maybe changing the API to allow for both options is a good idea
allowing to specify the fileName would help reducing the document size if the same image is included several times
This one is done now!
How it is done? Maybe I don't see something, but after some experiments and analysis of the ImageRun class, I see that file name is always randomly generated for each instance of ImageRun.
Simplest solution that I see is to add optional uniqueId to RegularImageOptions and SvgMediaOptions and use them when generating keys:
this.key = `${options.uniqueId || uniqueId()}.${options.type}`;
this.fallbackKey = `${options.fallback?.uniqueId || uniqueId()}.png`;
If this solution is acceptable, I can prepare a PR.
Edit:
Attaching minimal reproducible example: mre.txt
After running, we can see two png files.