25
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

株式会社VISIONARY JAPANAdvent Calendar 2023

Day 22

【img2pdf】アスペクト比がばらばらな画像をPDF化

Last updated at Posted at 2023-12-21

概要

アスペクト比や画像幅がばらばらの画像をPDF化したいのでimg2pdfとPILで実装してみた。
(専用ツールを使うのがめんどくさい人向けです)

まずはディレクトリ内の画像を一括PDF化してみる

img2pdfを使用しPDF化してみます。
このコードだけだとmacのプレビューのような余白はなく、また画像の横幅にばらつきがある場合がたつきのあるPDFになります。

jupyter notebook
import os
import re
import img2pdf

def convert_images_to_pdf(directory):
    # 並び替えて画像を取得
    image_files = sorted(
        [
            os.path.join(directory, filename)
            for filename in os.listdir(directory)
            if filename.lower().endswith(('.png', '.jpg', '.jpeg'))
        ],
        key=lambda x: [int(n) if n.isdigit() else n for n in re.split(r'(\d+)', x)],
    )

    if not image_files:
        print("指定された拡張子の画像ファイルは見つかりませんでした。")
        sys.exit(1)

    pdf_file_name = 'output.pdf' # 出力するpdf名
    pdf_bytes = img2pdf.convert(image_files)
    with open(pdf_file_name, "wb") as f:
        f.write(pdf_bytes)

    print("PDFファイルが作成されました。")

directory = '/path/to/input_directory/' # 画像が保存されているディレクトリパス
convert_images_to_pdf(directory)

予め、画像サイズを全て揃えて余白をつける

PILを使用し、PDF化する前にディレクトリ内の画像を編集します。

jupyter notebook
from PIL import Image
import os

def resize_image(image_path, target_width=800, margin=10):
    with Image.open(image_path) as image:

        old_width, old_height = image.size # 元画像のサイズを取得
        target_height = int((target_width / old_width) * old_height) # リサイズ後の高さを計算

        # 新しいサイズの画像を作成し、余白を含める
        resized_image = Image.new("RGB", (target_width, target_height), (255, 255, 255))
        resized_image.paste(image.resize((target_width - 2 * margin, target_height - 2 * margin)), (margin, margin))
        return resized_image


def resize_images(input_directory, output_directory, width=800):
    os.makedirs(output_directory, exist_ok=True)

    # ディレクトリ内の画像ファイルを取得
    image_files = [
        f
        for f in os.listdir(input_directory)
        if os.path.isfile(os.path.join(input_directory, f))
        and f.lower().endswith((".jpg", ".jpeg", ".png"))
    ]

    # 画像をリサイズして新しいディレクトリに保存
    for image_file in image_files:
        # 画像のパスを取得
        image_path = os.path.join(input_directory, image_file)
        
        # 横幅を指定した値に揃える
        resized_image = resize_image(image_path, width)

        # 新しい画像の保存パスを作成
        new_image_path = os.path.join(output_directory, image_file)

        # リサイズされた画像を保存
        resized_image.save(new_image_path)

    print("画像のリサイズが完了しました。")
    
input_directory = '/path/to/input_directory/' # 画像が保存されているディレクトリパス
output_directory = '/path/to/output_directory/' # リサイズされた画像が保存されるディレクトリパス
resize_images(input_directory, output_directory)

リサイズしてpdf化

最後に作成した関数を合わせて実行します。

jupyter notebook
resize_images(input_directory, output_directory)
convert_images_to_pdf(output_directory)

最後に

Pythonはできることが幅広い分、適当な専用ツールを探すことが疎かになっています。反省しなければ。

25
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?