Skip to content

Instantly share code, notes, and snippets.

@crazygit
Created September 1, 2025 01:28
Show Gist options
  • Save crazygit/1330c071170232c740ba5cc015c03a0a to your computer and use it in GitHub Desktop.
Save crazygit/1330c071170232c740ba5cc015c03a0a to your computer and use it in GitHub Desktop.

Revisions

  1. crazygit revised this gist Sep 1, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion photo.py
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    #
    # uv add pillow
    from PIL import Image, ImageOps

    # 打开原图
  2. crazygit created this gist Sep 1, 2025.
    41 changes: 41 additions & 0 deletions photo.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    #
    from PIL import Image, ImageOps

    # 打开原图
    input_path = "/path/to/input/image.jpg"
    img = Image.open(input_path)

    # 2寸照片尺寸:3.5cm x 5.3cm -> 换算像素 (300 dpi = 118.11 px/cm)
    cm_to_px = lambda cm: int(cm * 118.11)
    target_size = (cm_to_px(3.5), cm_to_px(5.3)) # 约 413 x 626 px

    # 调整尺寸
    photo = ImageOps.fit(img, target_size, Image.Resampling.LANCZOS)

    # 添加1像素黑色相框
    bordered_photo = ImageOps.expand(photo, border=1, fill="black")

    # 4R 照片纸:10.2 x 15.2 cm -> 换算像素
    paper_size = (cm_to_px(10.2), cm_to_px(15.2)) # 约 1205 x 1795 px
    paper = Image.new("RGB", paper_size, "white")

    # 计算每行每列能放几张
    pw, ph = paper_size
    fw, fh = bordered_photo.size
    cols = pw // (fw + 20) # 水平间距20px
    rows = ph // (fh + 20) # 垂直间距20px

    x_margin = (pw - cols * fw - (cols - 1) * 20) // 2
    y_margin = (ph - rows * fh - (rows - 1) * 20) // 2

    # 排版照片
    for r in range(rows):
    for c in range(cols):
    x = x_margin + c * (fw + 20)
    y = y_margin + r * (fh + 20)
    paper.paste(bordered_photo, (x, y))

    # 保存输出
    output_path = "/path/to/output/image.jpg"
    paper.save(output_path, "JPEG")
    output_path