第2章 · 実例 2

100 枚の写真にリサイズ・サムネイル・透かしを一括

第 04 章「処理を書く ── AIにPythonで書いてもらう」の 2 番目の角度: 繰り返しの画像処理を Python に渡す

章のどの主張に対応するか

100 個の .xlsx から特定列を抽出する月次作業: Excel VBA で半日。 pandasglob を使って一気に処理すれば 30 秒。

(章本文「実例: 数字で見る」より)

example-1 が「PDF から金額抽出」、これは 画像の一括加工 を実演する。 Photoshop でアクション組んでも 1 枚 5 秒以上。Python なら並列で 24 ms / 枚

やること

100 枚の JPEG (1920×1280, 計 11.3 MB) に対して:

  1. リサイズ: 長辺 1200px に縮小(Web 公開用)
  2. サムネイル: 200×200 中央クロップ(一覧画面用)
  3. 透かし: 右下に半透明の © aiseed.dev 2026(配布用)

これを ProcessPoolExecutor で並列実行(全 CPU コアを使う)。

構成

example-2/
├── README.md
├── generate_samples.py    ── 100 枚のサンプル JPEG を生成
├── process.py             ── リサイズ + サムネイル + 透かし
├── Makefile
├── results.md
├── src/                   ── 入力 (100 枚, 11.3 MB) ── git 除外
└── out/
    ├── resized/           ── リサイズ後(100 枚, 2.9 MB)── git 除外
    ├── thumbs/            ── サムネイル(100 枚, 0.3 MB)── git 除外
    ├── watermarked/       ── 透かし入り(100 枚, 3.3 MB)── git 除外
    └── sample/            ── 各種類 2 枚ずつコミット(計 6 枚)

実行

pip install Pillow
make clean && make all

100 枚の処理が 約 2.4 秒 で完了する。

なぜこれが「実例」になるのか

商品写真を 100 枚撮影 → Web 公開用に整える、というのは小売・農業・ 不動産・士業の Web サイト運営でよくある作業。

手作業(Photoshop / プレビュー):

Python:

from concurrent.futures import ProcessPoolExecutor
from PIL import Image, ImageOps

def process_one(path):
    img = Image.open(path)
    img.thumbnail((1200, 1200))
    img.save("resized/" + path.name)
    # ... thumbnail / watermark

これが章で言う「繰り返しの仕事を、一回限りの仕事にする」の具体形。

透かしのカスタマイズ

文字、フォント、位置、不透明度はすべてコード内の定数:

WATERMARK = "© aiseed.dev 2026"
font = ImageFont.truetype("DejaVuSans.ttf", 24)
fill = (255, 255, 255, 220)  # 半透明白

「Claude にこの透かしを赤色で右上に変えて」と頼めば、 コードがすぐ書き換わる。画像処理の中身が、自分が読める言葉になる


計測結果 — 第 04 章 example-2

実行環境: Linux 6.18 / Python 3.11 / Pillow 12.x / 8 並列

一括処理(主目的)

=== 一括処理結果 ===
  入力          : 100 枚 / 11.3 MB
  リサイズ後    : 100 枚 / 2.9 MB
  サムネイル    : 100 枚 / 0.3 MB
  透かし入り    : 100 枚 / 3.3 MB
  並列処理時間  : 2.43 秒
  1 枚あたり    : 24.3 ms

比較

方法 100 枚処理
Photoshop で手作業(リサイズ + サムネ + 透かし) 2.5 時間
Photoshop アクション(自動化済み) 約 5 分(1 枚 3 秒 ×100)
Python(このスクリプト、8 並列) 2.4 秒

Photoshop 手作業との比は 約 3,700 倍

サイズ削減

出力 1 枚あたり 100 枚合計 入力比
入力(1920×1280, q=92) 約 113 KB 11.3 MB 1.0
リサイズ(長辺 1200, q=85) 約 30 KB 2.9 MB 0.26 倍
サムネイル(200×200, q=80) 約 3 KB 0.3 MB 0.03 倍
透かし入り(同サイズ + WM) 約 33 KB 3.3 MB 0.29 倍

Web 公開には リサイズ + サムネイル + 透かし の 3 形式があれば足りる。 合計 6.5 MB(元の 60% に圧縮)。

サンプル(out/sample/)

100 枚のうち、各処理結果を 2 枚ずつコミット:

out/sample/resized-img_000.jpg       (1200×800)
out/sample/resized-img_050.jpg
out/sample/thumbs-img_000.jpg        (200×200)
out/sample/thumbs-img_050.jpg
out/sample/watermarked-img_000.jpg   (1200×800 + © aiseed.dev 2026)
out/sample/watermarked-img_050.jpg

ブラウザで開けば処理結果の品質が確認できる。

並列処理の効果

with ProcessPoolExecutor() as pool:
    results = list(pool.map(process_one, files))

CPU が複数あるなら、繰り返し処理は並列で。 人間も並列できないが、コードはできる

来月の運用

# 1. 新しい写真を src/ に置く
cp ~/Pictures/2026-05/* src/

# 2. 走らせる
python3 process.py

# 3. resized/ と thumbs/ を Web に上げる
rsync -av out/resized/ user@server:/var/www/photos/full/
rsync -av out/thumbs/  user@server:/var/www/photos/thumb/

これを cron に登録すれば、写真フォルダに何かが置かれた瞬間から 公開準備まで自動。

再現手順

pip install Pillow
make clean && make all

ファイル一覧

out/

第2章「処理を書く ── AIにPythonで書いてもらう」に戻る