Open baevpetr opened 1 year ago
Hi, I'll take a look at your problem over the weekend. There is another option, you can create a template and use the library to access presentation objects and change their contents depending on the business logic.
@baevpetr this is an interesting problem, one I might need to address myself at some point. Can you be more specific about what the problem is?
Is it that scaling applied to a "container" shape is not directly reflected on a "contained" shape?
There is no mechanism for getting this from the library so far. I expect your approach is pretty much what is required if you need that sort of thing. It's kind of an edge-case requirement in that most users of the library would never have an interest in that sort of thing, but could be important for document indexing.
If you can say more I'd be happy to think more with you about how it might make sense to support this sort of thing in the general case.
A good place to start might be seeing what PowerPoint reports for position and size when you select a shape inside a scaled group.
In 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
Hello, @scanny!
For a project, I'm trying to group/cluster/build a hierarchy of shapes on slides. Trying to do that using positions of a given shape and its sizes. For visualizing I'm using matplotlib library.
Here are screenshots from a .pptx file under investigation:
And here are plots with lines that represent the boundaries of every given shape on every slide:
Here enclosing boxes are group shapes with their own positions and sizes. For group shapes it's fine, but it's not fine for nested shapes...
Code that I'm using for correct coordinates:
We calculate scaling coefficients and use them to find out the correct size and position of every nested shape.
After that fix we have:
Am I doing something wrong and the library is capable of handling this?