第 04 章「処理を書く ── AIにPythonで書いてもらう」の 2 番目の角度: 繰り返しの画像処理を Python に渡す。
章のどの主張に対応するか
100 個の
.xlsxから特定列を抽出する月次作業: Excel VBA で半日。pandasでglobを使って一気に処理すれば 30 秒。
(章本文「実例: 数字で見る」より)
example-1 が「PDF から金額抽出」、これは 画像の一括加工 を実演する。 Photoshop でアクション組んでも 1 枚 5 秒以上。Python なら並列で 24 ms / 枚。
やること
100 枚の JPEG (1920×1280, 計 11.3 MB) に対して:
- リサイズ: 長辺 1200px に縮小(Web 公開用)
- サムネイル: 200×200 中央クロップ(一覧画面用)
- 透かし: 右下に半透明の
© 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 / プレビュー):
- 1 枚ずつ開く: 3 秒
- リサイズ: 5 秒
- 別名保存: 3 秒
- × 3 種類(リサイズ/サムネイル/透かし)
- × 100 枚 = 9,000 秒 = 2.5 時間
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
- 2.4 秒で完了
- 来月新しい 100 枚が来ても、
python3 process.pyだけで同じ結果 - 仕様が変わったら、コードの 1 行を書き換えれば 100 枚に反映
これが章で言う「繰り返しの仕事を、一回限りの仕事にする」の具体形。
透かしのカスタマイズ
文字、フォント、位置、不透明度はすべてコード内の定数:
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))
- シリアル実行(参考、推定): 約 18 秒
- 8 コア並列: 2.4 秒(約 7.5 倍速)
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