python-pptxで画像をセンタリングする


概要

python-pptxとPillow (PIL)を使って、PowerPointの中央に画像を挿入(センタリング)できるようにしました。

背景

python-pptxはpythonからPowerPointをつくることができるライブラリです。
非常に便利なのですが、スライドへ画像挿入するときの挿入位置は、画像左上の座標でしか指定しかできません。
センタリングをしたいなと思ったのですが、そのようなオプションがpython-pptxにあるのかよくわかりませんでした。
そこでPillowというライブラリで画像を別途読み込んで画像サイズを取得することで、センタリングを実現しました。

環境

macOS Catalina バージョン 10.15.3
python3.7.0

インストール

pip install python-pptx
pip install Pillow

コード

from pptx import Presentation
from pptx.util import Inches
from PIL import Image

IMG_PATH = "/path/to/img_file"
IMG_DISPLAY_HEIGHT = Inches(3) #スライドに表示するときの画像の高さ。とりあえず3インチとしておく。
SLIDE_OUTPUT_PATH = "test.pptx" #スライドの出力先パス

#スライドオブジェクトの定義
prs = Presentation() 

#スライドサイズを取得
SLIDE_WIDTH = prs.slide_width #
SLIDE_HEIGHT = prs.slide_height

#白紙のスライドを追加
blank_slide_layout = prs.slide_layouts[6] 
slide = prs.slides.add_slide(blank_slide_layout)

#画像サイズを取得してアスペクト比を得る
im = Image.open(IMG_PATH)
im_width, im_height = im.size
aspect_ratio = im_width/im_height

#表示された画像のサイズを計算
img_display_height = IMG_DISPLAY_HEIGHT
img_display_width = aspect_ratio*img_display_height

#センタリングする場合の画像の左上座標を計算
left = ( SLIDE_WIDTH - img_display_width ) / 2
top = ( SLIDE_HEIGHT - img_display_height ) / 2

#画像をスライドに追加
slide.shapes.add_picture(IMG_PATH, left, top, height = IMG_DISPLAY_HEIGHT)

#スライドを出力
prs.save(SLIDE_OUTPUT_PATH)

以上のコードにより下記のような、図がセンタリングされたパワポスライドを作ることができます。(テスト画像は筆者撮影)

Pillowの部分は元の画像のアスペクト比が計算できれば何でも良いので、例えばopencvでも代用可能です。
ドキュメントによるとpython-pptxにはsizeのプロパティをもつImageというクラスがあって、そこからsizeを取得することもできそうなのですが、具体的なやり方がわかりませんでした。
画像サイズ取得のためだけにPillowを使うのはスマートでないので、もしpython-pptx単体でのやり方をご存知な方がいたらご教授いただけると嬉しいです。

本記事は以上です。
ここまで読んでいただきありがとうございました。