ここでは EXIFのカメラ機種・レンズ別に画像をまとめてHTMLギャラリーを作る 実践例を紹介します。これを使えば「Canonで撮った写真」「iPhoneで撮った写真」「50mmレンズで撮った写真」などを自動で分類できます。
1. EXIFから機種・レンズ情報を取得
EXIFには以下のタグが含まれます:
- Make(メーカー名: Canon, Nikon, Apple など)
- Model(カメラ機種: EOS 5D, iPhone 12 など)
- LensModel(レンズ名: EF50mm f/1.8 など)
from pathlib import Path
from PIL import Image, ExifTags
# EXIFタグ辞書
EXIF_TAGS = {v: k for k, v in ExifTags.TAGS.items()}
def get_camera_info(img_path: Path):
"""カメラ機種とレンズ名を返す"""
make, model, lens = None, None, None
try:
with Image.open(img_path) as img:
exif = img._getexif()
if not exif:
return None, None
make = exif.get(EXIF_TAGS.get("Make"))
model = exif.get(EXIF_TAGS.get("Model"))
lens = exif.get(EXIF_TAGS.get("LensModel"))
except Exception:
pass
return (f"{make} {model}".strip() if model else make, lens)
Python2. 分類の仕組み
camera_dict[機種名] = [画像リスト]lens_dict[レンズ名] = [画像リスト]- HTMLで「機種別」「レンズ別」のページを生成
3. サンプル処理フロー
from collections import defaultdict
import shutil, html
src_dir = Path.home() / "Pictures" / "gallery_src"
out_dir = Path.home() / "Pictures" / "gallery_by_camera"
thumb_dir = out_dir / "thumbs"
img_copy_dir = out_dir / "images"
out_dir.mkdir(exist_ok=True)
thumb_dir.mkdir(exist_ok=True)
img_copy_dir.mkdir(exist_ok=True)
camera_dict = defaultdict(list)
lens_dict = defaultdict(list)
def make_thumbnail(src: Path, dst: Path, size=(240,240)):
with Image.open(src) as img:
img.thumbnail(size)
if img.mode != "RGB":
img = img.convert("RGB")
dst.parent.mkdir(parents=True, exist_ok=True)
img.save(dst, "JPEG", quality=85)
for img_path in src_dir.glob("*.jpg"):
cam, lens = get_camera_info(img_path)
cam = cam or "不明なカメラ"
lens = lens or "不明なレンズ"
thumb_path = thumb_dir / f"{img_path.stem}_thumb.jpg"
make_thumbnail(img_path, thumb_path)
copy_path = img_copy_dir / img_path.name
if not copy_path.exists():
shutil.copy(img_path, copy_path)
item = {
"full": f"images/{img_path.name}",
"thumb": f"thumbs/{thumb_path.name}",
"title": html.escape(img_path.stem),
}
camera_dict[cam].append(item)
lens_dict[lens].append(item)
Python4. HTML生成(例:カメラ機種別)
def render_gallery(title, groups, filename):
html_content = f"""<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{title}</title>
<style>
body {{ background:#111; color:#eee; font-family:sans-serif; }}
h2 {{ margin-top:24px; }}
.grid {{ display:grid; grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); gap:12px; }}
.card {{ background:#1b1b1b; border:1px solid #333; border-radius:8px; overflow:hidden; }}
.thumb {{ width:100%; height:auto; object-fit:cover; aspect-ratio:1/1; }}
.meta {{ padding:8px; font-size:12px; color:#bbb; }}
</style>
</head>
<body>
<header><h1>{title}</h1></header>
"""
for group, items in groups.items():
html_content += f"<h2>{group}({len(items)}枚)</h2><div class='grid'>"
for item in items:
html_content += f"""
<div class="card">
<a href="{item['full']}" target="_blank">
<img class="thumb" src="{item['thumb']}" alt="{item['title']}">
<div class="meta">{item['title']}</div>
</a>
</div>
"""
html_content += "</div>"
html_content += "</body></html>"
(out_dir / filename).write_text(html_content, encoding="utf-8")
# カメラ別ページ
render_gallery("カメラ機種別ギャラリー", camera_dict, "by_camera.html")
# レンズ別ページ
render_gallery("レンズ別ギャラリー", lens_dict, "by_lens.html")
Python5. 出力イメージ
- by_camera.html
- Canon EOS 5D(20枚)
- iPhone 12(15枚)
- Sony α7 III(10枚)
- by_lens.html
- EF50mm f/1.8(12枚)
- 24-70mm f/2.8(18枚)
- 不明なレンズ(5枚)
✅ まとめ
- EXIFのMake/Model/LensModel を使えば機種・レンズ別に分類可能
defaultdict(list)でグループ分けし、HTMLを自動生成- カメラやレンズごとの作風や傾向を振り返るのに便利


