Pythonで写真の詳細情報を取得する!EXIF情報取得

Python

PythonでEXIF情報を取得するには?

EXIF情報(Exchangeable Image File Format)はデジタルカメラやスマートフォンで撮影した写真に含まれる追加データのことです。写真を撮るときカメラは写真の内容だけでなくその写真に関するさまざまなEXIF情報がjpegファイルに保存されます。

EXIF情報には、以下のような多くの詳細が含まれています:

  1. 撮影日時:写真がいつ撮影されたかの日付と時間。
  2. カメラのメーカーとモデル:写真を撮ったカメラのブランドと型番。
  3. カメラの設定:露出時間(写真が光を感知した時間)、F値(レンズの開口部の大きさ)、ISO感度(カメラの光に対する感度)、焦点距離(レンズと被写体の距離)など、写真を撮るときのカメラの設定。
  4. 位置情報:GPS機能があるカメラであれば、写真がどこで撮影されたかの地理的な位置(緯度と経度)。
  5. 画像の方向:写真が横向きに撮影されたか、縦向きに撮影されたか。

写真が多くなってくると写真の管理をプログラムで分類して整理したくなる場合があります。例えば、撮影日時の情報を使って写真を時系列に並べたり、カメラメーカーごとで分類したりできます。

フォルダを指定してexifを取得するサンプルコード

exif情報を取得するサンプルコードを紹介します。

import os  # ファイルやディレクトリのパス操作に使用
from PIL import Image, ExifTags  # 画像処理とEXIF情報の抽出に使用
import pandas as pd  # データ分析とデータフレーム操作に使用

def get_exif(folder_path, specific_tags=None):
    """
    指定されたフォルダ内のJPEGファイルからEXIF情報を抽出し、データフレームとして返す関数。
    複数の特定のタグが指定された場合、FileNameを含むそれらのタグを指定された順に含むデータフレームを返す。

    Args:
        folder_path (str): JPEGファイルが含まれるフォルダのパス。
        specific_tags (list of str, optional): 抽出したい特定のEXIFタグ名のリスト。デフォルトはNone。

    Returns:
        pd.DataFrame: 抽出されたEXIF情報を含むデータフレーム。
    """
    # JPEGファイルのパスを格納するリストを初期化
    jpeg_files = []

    # フォルダ内の全ファイルをループ処理
    for f in os.listdir(folder_path):
        # ファイルがJPEG形式かどうかをチェック(小文字に変換してから判定)
        if f.lower().endswith(('.jpg', '.jpeg')):
            # ファイルのフルパスを生成してリストに追加
            file_path = os.path.join(folder_path, f)
            jpeg_files.append(file_path)
    
    
    # EXIFデータを格納するためのリストを初期化
    exif_data = []
    
    # 抽出したJPEGファイルのパスをループ処理
    for file_path in jpeg_files:
        # 画像を開き、EXIF情報を抽出
        with Image.open(file_path) as img:
            exif = img._getexif()
            
            if exif:
                # EXIF情報を格納するディクショナリを初期化(ファイル名をキーに含む)
                exif_info = {"FileName": os.path.basename(file_path)}
                
                # EXIF情報の各タグをループ処理
                for tag, value in exif.items():
                    # タグ名を取得
                    readable_tag = ExifTags.TAGS.get(tag, tag)
                    
                    # 特定のタグが指定されているか、または全タグを抽出する場合
                    if specific_tags and readable_tag in specific_tags:
                        exif_info[readable_tag] = value
                        
                    elif not specific_tags:
                        exif_info[readable_tag] = value
                        
                # 抽出したEXIF情報をリストに追加
                exif_data.append(exif_info)
    
    # データフレームの列の順番を調整
    if specific_tags:
        # FileNameを最初にして、指定されたタグの順番に列を並べる
        columns_order = ['FileName'] + specific_tags
        df = pd.DataFrame(exif_data, columns=columns_order)

    else:
        # 特定のタグが指定されていない場合、抽出した順に列を生成
        df = pd.DataFrame(exif_data)
    
    # DataFrameを返す
    return df




##############################################################
# 関数のテスト
if __name__ == "__main__":

    # 参照先フォルダを指定
    images_folder = "c:\\Photos\\2019-08-18"

    ## 特定のタグを指定して関数を呼び出す例
    df = get_exif(images_folder, ['ExifImageWidth', 'ExifImageHeight', 'DateTime', 'Make'])

    # DataFrameをExcelファイルに出力
    excel_path = "exif_data.xlsx"  # Excelファイルのパスを指定
    df.to_excel(excel_path, index=False)



    ## すべてのタグを出力する例
    df = get_exif(images_folder)

    # DataFrameをExcelファイルに出力
    excel_path = "exif_data_all.xlsx"  # Excelファイルのパスを指定
    df.to_excel(excel_path, index=False)


※EXCELはPythonの実行フォルダに出力されますので変更したい場合にはexcel_pathで出力先pathとファイル名を指定してください。

実行結果

筆者の環境では「特定のタグを指定して関数を呼び出す」とした場合次のようなEXCELが出力されます。

指定したタグがない場合ヘッダはできますが値が取れませんので注意してください。
この例の場合はC列が該当します。

画像で利用できるタグはexif_data_all.xlsxに記載されていますのでそちらを確認してください。
また、規格についてはhttps://www.cipa.jp/j/std/std-sec.htmlを参照ください。

最後に

以上がPythonでEXIF情報を取得する方法です。

写真の管理や整理をしたい方は試してみてはいかがでしょうか。

コメント

タイトルとURLをコピーしました