'Finding and using shape position Python pptx

I am trying to locate the position of a shape with specific text within it. After I get the position of the shape, I want to add an image at the same position as to highlight its location in the PowerPoint upon opening. Here is what I have so far:

from pptx import Presentation  
from pptx.util import Inches, Pt 

path_map = 'Path/TO.pptx'
prs = Presentation(path_map)
image_file = 'Path/TO.png'
search_str = 'Jack'
for slide in prs.slides:
    for shape in slide.shapes:
        if shape.has_text_frame:
            if(shape.text.find(search_str))!=-1:
                horiz_ = shape.left
                vert_ = shape.top
                height_ = Inches(1)
                width_ = Inches(1) 
                slide.shapes.add_picture(image_file, horiz_, vert_, width_, height_)
prs.save(path_map)

When run, no errors pop up, but the image is not added either, any suggestions on what I am missing?



Solution 1:[1]

Note that you are modifying the collection of shapes while you are enumerating its items. It may be the reason for the failure.

If you use Aspose.Slides for Python, you will do this as shown below:

import aspose.slides as slides

input_file_path = "example.pptx"
output_file_path = "example_out.pptx"
image_file_path = "image.png"
search_str = "Jack"

with slides.Presentation(input_file_path) as presentation:

    with open(image_file_path, 'rb') as image_stream:
        image = presentation.images.add_image(image_stream)

    for slide in presentation.slides:
        for shape_index in range(len(slide.shapes)):
            shape = slide.shapes[shape_index]
            if hasattr(shape, "text_frame") and shape.text_frame.text.find(search_str) != -1:
                    x = shape.x
                    y = shape.y
                    width = shape.width
                    height = shape.height
                    slide.shapes.add_picture_frame(slides.ShapeType.RECTANGLE, x, y, width, height, image)

    presentation.save(output_file_path, slides.export.SaveFormat.PPTX)

You can also evaluate Aspose.Slides Cloud SDK for Python for presentation manipulating. This REST-based API allows you to make 150 free API calls per month for API learning and presentation processing. The following code example demonstrates how to do the same with Aspose.Slides Cloud:

import asposeslidescloud
import shutil
import base64

from asposeslidescloud.configuration import Configuration
from asposeslidescloud.apis.slides_api import SlidesApi
from asposeslidescloud.models.picture_frame import PictureFrame
from asposeslidescloud.models.picture_fill import PictureFill

configuration = Configuration()
configuration.app_sid = "my_client_id"
configuration.app_key = "my_client_key"

slides_api = SlidesApi(configuration)

input_file_path = "example.pptx"
output_file_path = "example_out.pptx"
image_file_path = "image.png"
search_str = "Jack"

with open(input_file_path, "rb") as input_stream:
    slides_api.upload_file(input_file_path, input_stream)

with open(image_file_path, "rb") as image_stream:
    encoded_image_string = str(base64.b64encode(image_stream.read()), "utf-8")

slide_count = len(slides_api.get_slides(input_file_path).slide_list)

for slide_index in range(1, slide_count + 1):
    shape_count = len(slides_api.get_shapes(input_file_path, slide_index).shapes_links)
    for shape_index in range(1, shape_count + 1):
        shape = slides_api.get_shape(input_file_path, slide_index, shape_index)
        if hasattr(shape, "text") and shape.text.find(search_str) != -1:
            picture = PictureFrame()
            picture.x = shape.x
            picture.y = shape.y
            picture.width = shape.width
            picture.height = shape.height
            picture.picture_fill_format = PictureFill()
            picture.picture_fill_format.base64_data = encoded_image_string
            slides_api.create_shape(input_file_path, slide_index, picture)

result = slides_api.download_file(input_file_path)
shutil.copyfile(result, output_file_path)

I work as a Support Developer at Aspose.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrey Potapov