How to Get the Content’s Width and Height Instead of the Shape Box in Java?

Hello, using ShapeThumbnailBounds.Appearance generates an image larger than the text box, which is expected, but all methods return the width and height of the text box instead of the content. Is there a way to get the width and height of the content itself, rather than the text box?

Thank you

@dfinsolutions,
Thank you for posting the question. I need some time to investigate the issue. I will get back to you as soon as possible.

@dfinsolutions,
Thank you for your patience. Just to avoid any misunderstanding, could you please clarify whether you mean the sample SmartArt shape you provided above, or a different sample shape?

Yes, the attached SmartArt can be used as an example. shape.getWidth() and shape.getHeight() return the dimensions of the shape itself, but not the dimensions of its contents, which are larger than the shape

@dfinsolutions,
Thank you for the clarification. Unfortunately, I haven’t found a way to get the width and height of a shape’s actual content with Aspose.Slides.

We have opened the following new ticket(s) in our internal issue tracking system and will consider implementing this feature according to the terms mentioned in Free Support Policies.

Issue ID(s): SLIDESJAVA-39722

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

@dfinsolutions,
Our developers have investigated the case. Unfortunately, PowerPoint does not provide a way to get the content dimensions. However, you can retrieve the data for each shape in the SmartArt object and calculate the content dimensions yourself:

public void mainTest()
{
    Presentation presentation = new Presentation("smartart.pptx");
    ISlide slide = presentation.getSlides().get_Item(0);
    IShape shape = slide.getShapes().get_Item(0);

    Rectangle2D.Double contentSize = new Rectangle2D.Double(
            shape.getRawFrame().getX(),
            shape.getRawFrame().getY(),
            shape.getRawFrame().getWidth(),
            shape.getRawFrame().getHeight());
    for(ISmartArtNode smNode : ((ISmartArt) shape).getAllNodes())
    {
        for (ISmartArtShape smShape : smNode.getShapes())
        {
            if (smShape.getFrame().getRotation() != 0.0)
            {
                Rectangle2D.Double boundingBox = calculateBoundingBox(
                        smShape.getFrame().getX() + smShape.getFrame().getWidth() / 2,
                        smShape.getFrame().getY() + smShape.getFrame().getHeight() / 2,
                                smShape.getFrame().getWidth(),
                                smShape.getFrame().getHeight(),
                                smShape.getFrame().getRotation());
                contentSize = union(boundingBox, contentSize);
            }
        }
    }

    System.out.println("Content x: " + contentSize.getX());
    System.out.println("Content y: " + contentSize.getY());
    System.out.println("Content width: " + contentSize.getWidth());
    System.out.println("Content height: " + contentSize.getHeight());
}

public static Rectangle2D.Double calculateBoundingBox(double centerX, double centerY,
                                                          double width, double height,
                                                          double angleDegrees) {
    double angleRad = Math.toRadians(angleDegrees);
    double cos = Math.abs(Math.cos(angleRad));
    double sin = Math.abs(Math.sin(angleRad));

    double newWidth = width * cos + height * sin;
    double newHeight = width * sin + height * cos;

    double x = centerX - newWidth / 2.0;
    double y = centerY - newHeight / 2.0;

    return new Rectangle2D.Double(x, y, newWidth, newHeight);
}

private static Rectangle2D.Double union(Rectangle2D.Double rect1, Rectangle2D.Double rect2) {
    double minX = Math.min(rect1.getX(), rect2.getX());
    double minY = Math.min(rect1.getY(), rect2.getY());
    double maxX = Math.max(rect1.getX() + rect1.getWidth(),
            rect2.getX() + rect2.getWidth());
    double maxY = Math.max(rect1.getY() + rect1.getHeight(),
            rect2.getY() + rect2.getHeight());

    return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
}

Output:

Content x:      183.59991455078125
Content y:      19.77181570040662
Content width:  474.9714050292969
Content height: 412.64723642361685

hi @andrey.potapov, thank you, the solution mostly works great, but we found one case where the SmartArt is missing a child node.

When we parse the attached PowerPoint, the triangle shape is missing. We tried both smNode .getShapes() and smNode .getChildNodes() methods.

Could you take a look and see if this might be a bug?

Thank you

sm.pptx.zip (33.3 KB)

@dfinsolutions,
Thank you for reporting the issue. I need some time to investigate the issue. I will get back to you as soon as possible.

@dfinsolutions,
Thank you for your patience. I’ve reproduced the issue where the triangle shape is missing when calculating the bounds of the SmartArt object. Our developers will continue to investigate this case.