Replace images respecting size and positionning

input.docx (16,9 Ko)
imageB.png (2,2 Ko)
output.docx (17,1 Ko)

Hi,

How to replace images respecting size and positionning?
In my case images are behind the text.

Here is my attempt. But apparently images are not exactly rendered in the same positions (see attached files).

Document doc = new Document("input\\" + "input.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
  
NodeCollection<Shape> shapes = (NodeCollection<Shape>) doc.getChildNodes(NodeType.SHAPE, true);
Rectangle2D.Float bounds = new Rectangle2D.Float();
for (Shape shape : shapes)
{
    if (shape.hasImage()) 
    {
        bounds = shape.getBounds();
        System.out.println("img");
        shape.remove();
        float x = bounds.x;
        float y = bounds.y;
        System.out.println("x = " + x);
        System.out.println("y = " + y);
        String imageFileName = "input\\" + "imageB.png";
        Shape newImgShape = builder.insertImage(imageFileName);
        newImgShape.setWrapType(WrapType.NONE);
        newImgShape.setBehindText(true);
        newImgShape.setBounds(bounds);
        bounds = newImgShape.getBounds();
      
        x = bounds.x;
        y = bounds.y;
        System.out.println("xnew = " + x);
        System.out.println("ynew = " + y);
    }
}
doc.save("output\\" + "output.docx");

@Nkorbl If your requirement is simply replace the image in the existing image shape, you can simply use ImageData.setImage. For example see the following code:

Document doc = new Document("C:\\Temp\\input.docx");
NodeCollection<Shape> shapes = (NodeCollection<Shape>)doc.getChildNodes(NodeType.SHAPE, true);
for (Shape shape : shapes)
{
    if (shape.hasImage())
        shape.getImageData().setImage("C:\\Temp\\imageB.png");
}
doc.save("C:\\Temp\\out.docx");

@alexey.noskov Thanks it solves placement and size in one line.
But unfortunately images are now replaced by “the picture can’t be displayed” frames…

output.docx (9,8 Ko)

@Nkorbl Unfortunately, I cannot reproduce the problem on my side. Here is the output produced on my side using the above code and the latest 24.1 version of Aspose.Words for Java: out.docx (11.9 KB)

I tried with 24.1 version and still have the same problem. Might be a MS Word settings issue then.
(I use MS Word 2021 for information)

@Nkorbl I have inspected your output document and there are no images inside. Do you postprocess the document somehow on your side? Could you please attach output document produced on your side using 24.1 version?

output_24.1.docx (20,2 Ko)
image.png (15,1 Ko)

@alexey.noskov I attached files including a screenshot of what I see. Concerning postprocessing I’m not doing anything else there is no additionnal code.

@Nkorbl It is really strange. I still cannot reproduce the problem on my side. For some reason the images are not present in your output document. If look inside document there is no reference to image in blip fill:

<a:blip cstate="print" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

And here is my output:

<a:blip r:embed="rId4" cstate="print" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

netbeansProject.jpg (127,3 Ko)
wordOutput.jpg (29,7 Ko)
inputFolder.jpg (13,1 Ko)
outputFolder.jpg (19,1 Ko)
output.docx (20,2 Ko)

@alexey.noskov Yes really weird it is basically a one line code I don’t get it. I just rebuilt a project in another computer but same result. (Office 2016)
By the way I’m using Netbeans as IDE but I don’t think that is a useful information…

@Nkorbl Could you please create a simple application that will allow us to reproduce the problem on our side and attach it here? What is your environment where the problem occurs?

@alexey.noskov Created a simple Java application with Ant.

netbeans_files_tab.png (59,9 Ko)
netbeans_projects_tab.png (55,9 Ko)

Project archive:
https://mega.nz/file/Ib1GyC5B#l4LGl-RgsZJY56YVbTbdcSvk5JjBmmFyx0Q315DlAHk

@Nkorbl Thank you for additional information. The problem is reproducible on my side. It looks like the image cannot be accessed from the project folder. The code works fine if read the image into byte array. Please try modifying the code like this:

Document doc = new Document("input\\" + "input.docx");
NodeCollection<Shape> shapes = (NodeCollection<Shape>)doc.getChildNodes(NodeType.SHAPE, true);
final String imageFileName = "input\\" + "imageB.png";
byte[] imageBytes = Files.readAllBytes(Paths.get(imageFileName));
for (Shape shape : shapes)
{
    if (shape.hasImage())
    {
        shape.getImageData().setImageBytes(imageBytes);
    }
}
doc.save("output\\" + "output.docx");

@alexey.noskov Oh I see, I naively thought that the argument was the same for DocumentBuilder.insertImage method.

insertImage(String fileName)
and
setImage(String fileName)
because surprisingly I didn’t have this problem with the insertImage method.

But now with your proposal it works
setImageBytes(byte[] value)

Thank’s a lot for your patience Alexey, really appreciated.

@Nkorbl It is perfect the you managed to make it work. Please feel free to ask in case of any other issues. We are always glad to help you.