Python PDFに複数の画像ファイルを1ページに貼り付ける枚数を指定して出力、またワードへ変換する。

 本記事では、pythonにて複数の画像ファイルを1ページに並べる数を指定してpdfに貼り付けて保存し、さらに作成したpdfファイルをMicrosoft OfficeのWordへ変換する雛形コードを載せました。使用するライブラリは「pillow」「reportlab」「pdf2docx」です。

下図は各頁に6枚の画像を貼り付けた場合の出力結果です。

下図は各頁に8枚の画像を貼り付けた場合の出力結果です。

 

■ライブラリのインストール

pip install pillow
pip install reportlab
pip install pdf2docx

 

■本プログラム

import glob
from PIL import Image
from reportlab.pdfgen import canvas
from pdf2docx.main import parse

# 貼り付ける画像の配置位置を調整する関数
def calculate_positions(image_paths, images_per_page, page_width, page_height):
    margin = 20

    # 横に並べる画像の数を2とし、ページの幅に合わせて余白が小さくなるように調整
    spacing_x = (page_width - 2 * margin) // 2
    spacing_y = (page_height - 2 * margin) // (images_per_page // 2)

    x_positions = []
    y_positions = []

    for i in range(images_per_page):
        row = i // 2
        col = i % 2
        x = margin + col * spacing_x
        y = page_height - margin - row * spacing_y
        x_positions.append(x)
        y_positions.append(y)

    # 画像の余白を考慮して配置位置を微調整
    for i in range(images_per_page):
        if i < len(image_paths):
            image_path = image_paths[i]
            image = Image.open(image_path)

            # グリッドに合わせた幅と高さを計算
            target_width = spacing_x * 0.8
            target_height = target_width * image.height / image.width

            # 画像がグリッドの高さよりも高い場合、高さに合わせる
            if target_height > spacing_y:
                target_height = spacing_y * 0.8
                target_width = target_height * image.width / image.height

            # 余白を考慮して配置位置を微調整
            x_positions[i] += (spacing_x - target_width) / 2
            y_positions[i] -= (spacing_y - target_height) / 2

    return x_positions[:images_per_page], y_positions[:images_per_page]

# 画像を貼り付けてpdfファイルで保存する関数
def images_to_pdf(image_paths, output_pdf, images_per_page=4, page_width=595, page_height=842):
    pdf = canvas.Canvas(output_pdf, pagesize=(page_width, page_height))

    # 1ページに指定数の画像を配置するためのループ
    for i in range(0, len(image_paths), images_per_page):
        x_positions, y_positions = calculate_positions(image_paths[i:i+images_per_page], images_per_page, page_width, page_height)

        for j in range(images_per_page):
            if i + j < len(image_paths):
                image_path = image_paths[i + j]
                image = Image.open(image_path)

                # グリッドに合わせた幅と高さを計算
                target_width = page_width // 2 * 0.8
                target_height = target_width * image.height / image.width
                image.thumbnail((target_width, target_height))

                x, y = x_positions[j], y_positions[j]
                pdf.drawImage(image_path, x, y - image.size[1], width=image.size[0], height=image.size[1])

        pdf.showPage()

    pdf.save()

def main():
    # 画像ファイルのパス
    image_paths = glob.glob("./dir_img/*.jpg")

    # 1ページに並べる画像の数
    images_per_page_list = [4, 6, 8]

    for images_per_page in images_per_page_list:
        # 保存するpdfのファイル名
        output_pdf = f"output_{images_per_page}_per_page.pdf"
        # 画像を貼り付けたpdfファイルを出力する
        images_to_pdf(image_paths, output_pdf, images_per_page)

        # 保存するワードのファイル名
        output_docx = output_pdf[:-4] + '.docx'
        # pdfファイルをワードへ変換する
        parse(output_pdf, output_docx)

if __name__ == "__main__":
    main()

以上

<広告>