Fit image to table cell width


#1

We are using Apose.Words for Java 19.6.

We are trying to insert images using DocumentBuilder.insertImage and resizing them to scale to the containing table cell by using the cell’s cellformat.getwidth() method. This works most of the time but in one scenario it doesn’t. If a table is inserted into another table and the nested table has width 100%, cellformat.getwidth() returns as width the page width instead of the width of the outer table’s cell.

Is there a way to get the correct width? Document.updateTableLayout() works sometimes, but not always. Or perhaps there’s a simpler way to resize an image to fill the containing cell?


#2

@bmpi

To ensure a timely and accurate response, please attach the following resources here for testing:

  • Your input Word document.
  • Please attach the output Word file that shows the undesired behavior.
  • Please attach the expected output Word file that shows the desired behavior.
  • Please create a simple Java application ( source code without compilation errors ) that helps us to reproduce your problem on our end and attach it here for testing.

As soon as you get these pieces of information ready, we will start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip and upload them.


#3

The situation has changed a bit. We have solved the above mentioned problem by using layoutEnumerator.getRectangle().getWidth(). But there’s a new problem. If for example the parent table has a width of 4cm, and the nested table has a width of 16cm, the image is resized to 16cm when the nested table is inserted into the parent table. If you do it inside word however the nested table is automatically resized. We would expect the image that is inserted into the nested table to be resized to 4cm. Here’s the code:

    Document documentA = new Document("input.docx");
    DocumentBuilder builderA = new DocumentBuilder(documentA);
    Table parent = null;
    Table nested = null;
    Boolean first = true;
    for (Object node : documentA.getChildNodes(com.aspose.words.NodeType.TABLE, true)) {
        if (first) {
            parent = (Table)node;
            first = false;
        } else {
            nested = (Table)node;
            break;
        }
    }
    builderA.moveTo(parent.getRows().get(0).getCells().get(0).getFirstParagraph());        
    Table copy = (Table)nested.deepClone(true);
    com.aspose.words.CompositeNode paragraph = builderA.getCurrentParagraph();
    com.aspose.words.CompositeNode body = paragraph.getParentNode();
    body.insertBefore(copy, paragraph);
    builderA.moveTo(copy.getRows().get(0).getCells().get(0).getFirstParagraph());
    LayoutEnumerator layoutEnumerator = new LayoutEnumerator(documentA);
    Object e = new LayoutCollector(documentA).getEntity(copy.getRows().get(0).getCells().get(0).getFirstParagraph());
    layoutEnumerator.setCurrent(e);
    layoutEnumerator.moveParent();
    Rectangle2D.Float rect = layoutEnumerator.getRectangle();
    double width2 = rect.getWidth() - copy.getRows().get(0).getCells().get(0).getCellFormat().getLeftPadding() - copy.getRows().get(0).getCells().get(0).getCellFormat().getRightPadding();
    Shape img2 = builderA.insertImage("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><svg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><path d='M80,67C47,121-25,60,10,22C5,89,70,80,80,67zM30,16C2,42,56,87,80,47C70,57,24,57,30,16M50,10C45,34,72,37,80,31C57,55,32,21,50,10z' fill='#4082ae'/></svg>".getBytes());
    img2.setAspectRatioLocked(true);
    img2.setWidth(width2); 
    documentA.save("output.docx");

The attached zip file has the documents. Expected.docx has the image resized to the expected width. Can you have a look at that please?

documents.zip (28.8 KB)


#4

@bmpi

Please remove the following line of code from your code to get the desired output.

img2.setWidth(width2);


#5

But that line is needed to resize the image to fit the cell. Unless you are saying that Aspose.Words automatically resizes the image when inserting it?


#6

@bmpi

You are using DocumentBuilder.InsertImage method (Byte[]). This method inserts an image that is inserted inline and at 100% scale. You can use DocumentBuilder.InsertImage method (Byte[], Double, Double) method to get the desired output.


#7

Yes, that might be true. But we’re trying to rescale the image proprtionally so that the width of the image is the same as the width of the cell. I think in this case the main problem is that layoutEnumerator.getRectangle() returns a rectangle that has a width of 16cm instead of 4cm. So my question mainly becomes: how do you reliably get the width of a nested cell?