ぱいそん Exif情報 csv化
にゃあにゃあw
Exif情報を csv化 する
pythonスクリプト
【Gemini】様 に 丸投げ!!!
# ==== 【Gemini】様
データベースやExcel(スプレッドシート)で読み込んで分析するのに最適な形式にまとめています。
### Exif一括抽出&CSV出力スクリプト
以下のコードを、例えば `Exif-To-CSV.py` という名前で保存してご活用ください。
```python
import os
import csv
from PIL import Image, ExifTags
# ==========================================
# ★設定エリア★
# 1. 解析したい画像が入っているフォルダのパス指定
TARGET_DIR = r"D:\_Exif-Rename"
# 2. 出力するCSVファイルの保存先指定
OUTPUT_CSV = r"D:\_Exif-Rename\Exif_Database.csv"
# 対象とする画像の拡張子
IMAGE_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.tiff', '.webp')
# ==========================================
def get_tag_name(tag_id):
"""ExifタグIDから人間が読めるタグ名を取得する"""
return Image.ExifTags.TAGS.get(tag_id, f"Unknown(0x{tag_id:04x})")
def clean_value(val):
"""CSV出力用にバイナリデータや非表示文字(ヌル文字等)を整形する"""
if val is None:
return ""
if isinstance(val, bytes):
try:
val = val.decode('utf-8', errors='ignore')
except Exception:
val = repr(val)
# 制御文字(ヌル文字 \x00 等)の除去
val_str = str(val).replace('\x00', '').strip()
return val_str
def process_images_to_csv(target_dir, output_csv):
print("=" * 60)
print(f"【スキャン開始】対象フォルダ: {target_dir}")
print("=" * 60)
if not os.path.exists(target_dir):
print(f"[ERROR] 指定されたフォルダが存在しません: {target_dir}")
return
# 全ファイルから検出されたすべてのExifタグ名を動的に集計(CSVのヘッダーにするため)
# 共通ヘッダー(ファイル情報)
base_headers = ["ファイルパス", "ファイル名", "画像幅(px)", "画像高さ(px)"]
all_exif_tags = set()
# 抽出結果を一時保持するリスト
records = []
# 1. フォルダ内を再帰的にスキャン
file_count = 0
for root, _, files in os.walk(target_dir):
for file in files:
if file.lower().endswith(IMAGE_EXTENSIONS):
file_path = os.path.join(root, file)
file_count += 1
record = {
"ファイルパス": file_path,
"ファイル名": file,
"画像幅(px)": "",
"画像高さ(px)": ""
}
try:
with Image.open(file_path) as img:
record["画像幅(px)"] = img.width
record["画像高さ(px)"] = img.height
exif = img.getexif()
if exif:
# 1階(メインIFD)の読み込み
for tag_id, value in exif.items():
tag_name = get_tag_name(tag_id)
record[tag_name] = clean_value(value)
all_exif_tags.add(tag_name)
# 2階(サブIFD: 0x8769)の読み込み
sub_exif = exif.get_ifd(0x8769)
if sub_exif:
for tag_id, value in sub_exif.items():
tag_name = get_tag_name(tag_id)
record[tag_name] = clean_value(value)
all_exif_tags.add(tag_name)
except Exception as e:
print(f"[WARNING] 読み込み失敗 ({file}): {e}")
records.append(record)
print(f"\n[INFO] 対象画像ファイル数: {file_count} 件")
print(f"[INFO] 検出されたExif項目数: {len(all_exif_tags)} 種類")
# 2. CSVファイルの書き出し
# タグ名をアルファベット順にソートしてヘッダーを作成
sorted_exif_tags = sorted(list(all_exif_tags))
fieldnames = base_headers + sorted_exif_tags
try:
# Excelで開いたときに文字化けしないよう utf-8-sig (BOM付きUTF-8) で出力
with open(output_csv, mode='w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for rec in records:
writer.writerow(rec)
print("\n" + "=" * 60)
print(f"【完了】CSVデータベースを出力しました!")
print(f"保存先: {output_csv}")
print("=" * 60)
except Exception as e:
print(f"[ERROR] CSVファイルの書き出しに失敗しました: {e}")
if __name__ == "__main__":
process_images_to_csv(TARGET_DIR, OUTPUT_CSV)
### ✨ このスクリプトの工夫ポイント
1. **2階(サブIFD)も漏らさず取得**
以前のチェッカー同様、F値・焦点距離・シャッタースピードやサブセコンド(マイクロ秒)が眠っている **「2階の隠し部屋 (0x8769)」** も完全走査して取得します。
2. **全画像のタグを動的に自動集計**
画像によって「入っているExif項目」が異なる場合でも、フォルダ内の全画像をチェックして**存在する全てのExifタグを列挙し、自動でCSVの列(ヘッダー)を作成**します。
3. **バイナリゴミ・ヌル文字の自動除去**
以前問題になった `\x00` や末尾の空文字などを自動的にクリア(サニタイズ)してから書き込むため、Excel等で読み込んだときに崩れません。
4. **Excelでの文字化け防止 (`utf-8-sig`)**
出力時のエンコーディングに `utf-8-sig` を採用しているため、生成されたCSVをそのままExcelで開いても文字化けしません。
5. **画像サイズ(幅・高さ)も自動付与**
Exif情報とは別に、実際の画像ピクセルサイズ(幅・高さ)も自動取得してCSVの先頭に追加します。
### 💡 使い方
1. スクリプト冒頭の `TARGET_DIR`(解析したいフォルダ)と `OUTPUT_CSV`(出力先CSVのパス)を環境に合わせて書き換えてください。
2. 実行すると、指定したフォルダ内の画像を全件走査し、CSVが生成されます。
# ==============================