Created
October 26, 2025 03:00
-
-
Save silasolla/48e34b90dfa9651a22b66efc61ef4bbc to your computer and use it in GitHub Desktop.
証明写真のデータをトリミングしてたくさん並べてコンビニで印刷できるようにする
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import argparse | |
| from PIL import Image | |
| from reportlab.lib.pagesizes import A4 | |
| from reportlab.pdfgen import canvas | |
| import os | |
| def create_photo_pdf(image_path, output_path): | |
| # A4 サイズ (pt) | |
| a4_width, a4_height = A4 | |
| # 写真サイズ(cm → pt) | |
| img_width = 2.0 * 28.35 | |
| img_height = 2.5 * 28.35 | |
| # マージン設定 (印刷端を避けるため大きめ) | |
| page_margin = 20 # 20pt → 0.7cm | |
| # 配置間の余白 | |
| spacing = 10 # 10pt → 0.35cm | |
| # 画像を中央トリミングしてアスペクト比を調整 | |
| img = Image.open(image_path) | |
| src_w, src_h = img.size | |
| target_ratio = img_width / img_height | |
| src_ratio = src_w / src_h | |
| if src_ratio > target_ratio: | |
| new_width = int(src_h * target_ratio) | |
| left = (src_w - new_width) // 2 | |
| img = img.crop((left, 0, left + new_width, src_h)) | |
| else: | |
| new_height = int(src_w / target_ratio) | |
| top = (src_h - new_height) // 2 | |
| img = img.crop((0, top, src_w, top + new_height)) | |
| tmp_path = "_tmp_img.jpg" | |
| img.save(tmp_path) | |
| # PDF 作成 | |
| c = canvas.Canvas(output_path, pagesize=A4) | |
| # 配置可能エリア (マージンを除いた領域) | |
| usable_w = a4_width - 2 * page_margin | |
| usable_h = a4_height - 2 * page_margin | |
| # 横縦に並べられる個数を計算 | |
| cols = int((usable_w + spacing) // (img_width + spacing)) | |
| rows = int((usable_h + spacing) // (img_height + spacing)) | |
| # 全体を中央寄せ配置 | |
| total_w = cols * img_width + (cols - 1) * spacing | |
| total_h = rows * img_height + (rows - 1) * spacing | |
| start_x = (a4_width - total_w) / 2 | |
| start_y = (a4_height - total_h) / 2 | |
| # 描画 | |
| y = start_y + total_h - img_height | |
| for _ in range(rows): | |
| x = start_x | |
| for _ in range(cols): | |
| c.drawImage(tmp_path, x, y, img_width, img_height) | |
| x += img_width + spacing | |
| y -= img_height + spacing | |
| c.save() | |
| os.remove(tmp_path) | |
| print(f"PDF 生成完了: {output_path}") | |
| if __name__ == "__main__": | |
| parser = argparse.ArgumentParser( | |
| description="画像を縦 2.5 cm × 横 2.0 cm にして A4 中央に配置した PDF を生成します." | |
| ) | |
| parser.add_argument("image", help="入力画像ファイル名") | |
| parser.add_argument("-o", "--output", default="output.pdf", help="出力 PDF ファイル名 (省略時: output.pdf)") | |
| args = parser.parse_args() | |
| create_photo_pdf(args.image, args.output) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment