Skip to content

Instantly share code, notes, and snippets.

@silasolla
Created October 26, 2025 03:00
Show Gist options
  • Select an option

  • Save silasolla/48e34b90dfa9651a22b66efc61ef4bbc to your computer and use it in GitHub Desktop.

Select an option

Save silasolla/48e34b90dfa9651a22b66efc61ef4bbc to your computer and use it in GitHub Desktop.
証明写真のデータをトリミングしてたくさん並べてコンビニで印刷できるようにする
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