Wenyi Yan
Wenyi Yan

Reputation: 85

How to crop an image by using python-pptx after it inserted into slide?

I've already insert an image into pptx by using python-pptx.

My question is: How to CROP (Not adjust ratio) the image after it get inserted. Let's say crop the top by 1 inch, and crop the bottom by 2 inchs.

My original code as below. Would like to know how to modify the code based on my code?

from pptx import Presentation 
from pptx.util import Inches

img_paths = ['abc.png']


prs = Presentation() 
prs.slide_width = Inches(15)
prs.slide_height = Inches(9)
blank_slide_layout = prs.slide_layouts[0] 


slide = prs.slides.add_slide(blank_slide_layout)


left = Inches(0)
top = Inches(1)
pic = slide.shapes.add_picture(img, left, top, Inches(15))    


prs.save('test.pptx')

Upvotes: 0

Views: 2675

Answers (2)

Joe
Joe

Reputation: 7161

The most intuitive and clean solution I could find is this one:

from PIL import Image

def _add_image(slide, placeholder_id, image_url):
    placeholder = slide.placeholders[placeholder_id]

    # Calculate the image size of the image
    im = Image.open(image_url)
    width, height = im.size

    # Make sure the placeholder doesn't zoom in
    placeholder.height = height
    placeholder.width = width

    # Insert the picture
    placeholder = placeholder.insert_picture(image_url)

    # Calculate ratios and compare
    image_ratio = width / height
    placeholder_ratio = placeholder.width / placeholder.height
    ratio_difference = placeholder_ratio - image_ratio

    # Placeholder width too wide:
    if ratio_difference > 0:
        difference_on_each_side = ratio_difference / 2
        placeholder.crop_left = -difference_on_each_side
        placeholder.crop_right = -difference_on_each_side
    # Placeholder height too high
    else:
        difference_on_each_side = -ratio_difference / 2
        placeholder.crop_bottom = -difference_on_each_side
        placeholder.crop_top = -difference_on_each_side

Use it like this with the second parameter being the index of the placeholder (powerpoint internal index, not a list index!)
_add_image(slide, 1, "003.png")

Source: https://github.com/scanny/python-pptx/issues/176#issuecomment-412700636

Upvotes: 0

SyntaxRules
SyntaxRules

Reputation: 2206

You can crop the pictures using the picture.crop_* methods. Documentation is found here:

https://python-pptx.readthedocs.io/en/latest/api/shapes.html#picture-objects

However the crop methods take a percentage of the total image that you want to crop, and you said you want to specify inches. To do so, we have to calculate the percentage to remove. Like so:

from pptx import Presentation 
from pptx.util import Inches

img_paths = ['abc.png']


prs = Presentation() 
prs.slide_width = Inches(15)
prs.slide_height = Inches(9)
blank_slide_layout = prs.slide_layouts[0] 


slide = prs.slides.add_slide(blank_slide_layout)


left = Inches(0)
top = Inches(1)
pic = slide.shapes.add_picture(img, left, top, Inches(15))    

crop_top_in = Inches(1)
crop_bottom_in = Inches(2)

pic.crop_top = crop_top_in / pic.height.inches
pic.crop_bottom = crop_bottom_in / pic.height.inches

prs.save('test.pptx')

Upvotes: 0

Related Questions