python-pptx icon indicating copy to clipboard operation
python-pptx copied to clipboard

Shape of group type has incorrect size

Open YuMingtao0503 opened this issue 1 year ago • 4 comments

n some cases, the position and size of group type shapes are incorrect, but I have found that even if they are in the wrong position, their relative positions are still relatively accurate. Therefore, there is a way to convert them

prs = Presentation("your_ppt.pptx")
slide = prs.slides[13]
for m,shape in enumerate(slide.shapes):  
    if shape.shape_type == 6:
        # true size and xy
        group_top_left_x = shape.left
        group_top_left_y = shape.top
        group_width = shape.width
        group_height = shape.height
        # false size and xy
        shape_top_left_x = min([ sp.left for sp in shape.shapes])
        shape_top_left_y = min([ sp.top for sp in shape.shapes])
        shape_width = max([sp.left + sp.width for sp in shape.shapes]) - shape_top_left_x
        shape_height = max([sp.top + sp.height for sp in shape.shapes]) - shape_top_left_y
        # scale xy
        px = group_width/shape_width
        py = group_height/shape_height
        group_shape_xy = []
        for n,sp in enumerate(shape.shapes):
            group_shape_left = (sp.left - shape_top_left_x) * group_width /shape_width + group_top_left_x
            group_shape_top = (sp.top - shape_top_left_y) * group_height /shape_height + group_top_left_y
            group_shape_width = sp.width * group_width / shape_width
            group_shape_height = sp.height * group_height/shape_height
            group_shape_xy.append([int(group_shape_left),int(group_shape_top),int(group_shape_width),int(group_shape_height)])

then group_shape_xysaved relatively real location information

YuMingtao0503 avatar Nov 07 '23 12:11 YuMingtao0503

I also met the same problem, and this solution solves my problem. Thank u very much.

devotedtaylor avatar Dec 15 '23 03:12 devotedtaylor

@YuMingtao0503 thanks a lot. Solves my problem

AliMamed avatar Jun 04 '24 08:06 AliMamed

@YuMingtao0503

Hi, thank you for your solution—it's been really helpful!

However, I've encountered a "divide by zero" issue when implementing it in my code.

Here's my code:

def parse_groupshape(groupshape: GroupShape):
    assert isinstance(groupshape, GroupShape)
    group_top_left_x = groupshape.left
    group_top_left_y = groupshape.top
    group_width = groupshape.width
    group_height = groupshape.height
    
    # Calculate false size and position
    shape_top_left_x = min([sp.left for sp in groupshape.shapes])
    shape_top_left_y = min([sp.top for sp in groupshape.shapes])
    shape_width = (
        max([sp.left + sp.width for sp in groupshape.shapes]) - shape_top_left_x
    )
    shape_height = (
        max([sp.top + sp.height for sp in groupshape.shapes]) - shape_top_left_y
    )
    
    # Scale position and size
    group_shape_xy = []
    for sp in groupshape.shapes:
        group_shape_left = (
            (sp.left - shape_top_left_x) * group_width / shape_width + group_top_left_x
        )
        group_shape_top = (
            (sp.top - shape_top_left_y) * group_height / shape_height + group_top_left_y
        )
        group_shape_width = sp.width * group_width / shape_width
        group_shape_height = sp.height * group_height / shape_height
        group_shape_xy.append(
            {
                "left": Length(group_shape_left),
                "top": Length(group_shape_top),
                "width": Length(group_shape_width),
                "height": Length(group_shape_height),
            }
        )
    return group_shape_xy

Does anyone have any suggestions on how to resolve this "divide by zero" problem?

Force1ess avatar Aug 21 '24 04:08 Force1ess

Not only divide by zero, some time it will give a error position when parse nested group shape

Force1ess avatar Sep 06 '24 08:09 Force1ess