見出し画像

Python と 外部ライブラリーの PILLOW を使って撮影情報を文字列にして csv ファイルとして保存する

絞り、シャッタースピード、感度などの撮影情報をテキストにして、csv ファイルとして保存する Python スクリプトを作った。

動作を確認した環境
MacOS Ventura 13.6、Python 3.10
確認したカメラ
Nikon、Olympus、OM Digital Solutions の一部のモデル

外部ライブラリー PILLOW を使う

自分の場合、環境構築などという面倒なことはしたくない。それをやるだけのメリットが面倒くささを上回るので。だから、インストーラーを使ってインストールしただけで Python を使っている。そんな環境。

*.py というファイルをダブルクリックすれば動作する。

使い方

撮影情報を取り出したい画像ファイルとスクリプトを同じフォルダーに入れる。

スクリプトを実行すると、csv ファイル "Shooting_Information.csv" ができあがる。

csvファイルの1列目にファイル名、2列目に撮影情報が収められている。
撮影情報は次の7項目を、コンマで区切って結合したテキストである。

  1. カメラのメーカー名

  2. カメラのモデル名

  3. レンズ

  4. 撮影日時

  5. 絞り

  6. シャッタースピード

  7. 感度

情報がない場合には、左に詰める。

Script

# -*- coding: utf-8 -*-
# 2024-07-25

import sys
import os
import csv
import glob
import re
from PIL import Image
#from PIL import ExifTags # タグの名称を確認しない場合は、不要

def main():
# 撮影情報を csv に保存する。
# 2023-08-15 11:06:31, F8.0, 1/500sec, ISO12800
# PILLOW ライブラリーを使う。

# 対象ファイル形式
# TIFF 画像 (*.tif、*.TIF、*.tiff、*.TIFF)
# JPEG 画像 (*.jpg、*.JPG、*.jpeg、*.JPEG)

    # 正規表現、*.jpg、*.jpeg、*.tif、*.tiff にマッチ、大文字小文字の区別なし
    pattern_img_file = re.compile('.*\.(JPE?G|TIF?F)$', re.IGNORECASE)

    # csv ファイルのタイトル行を作る
    shooting_information = [['ファイル名', '撮影情報']]

    # このファイルと同じフォルダーにあるファイルをリストアップする
    files = glob.glob('./*.*')
    # 対象のファイルがなかったら終了
    if len(files) == 0:
        sys.exit()
    for file in files:
        if pattern_img_file.match(file):           # 正規表現のパターンにマッチしたら
            with Image.open(file) as photo:        # PILLOW で写真ファイルを読み込む
                original_path = photo.filename               # 画像ファイルのパスとファイル名
                file_name = os.path.basename(original_path)  # オリジナルファイルの名称
                width = photo.width        # 幅
                height = photo.height      # 高さ
                # 画像の基本情報を入れたリストを作る
                # 幅と高さは、「幅 x 高さ px」の形に加工する
                l0 = [file_name, str(width) + ' x ' + str(height) + ' px']

                # 画像の情報をゲットする、辞書型
                primary_entry = photo.getexif()

                # Tag の名称を確認するためのルーチン、開発用
                #for k, v in primary_entry.items():
                #   tag_name = ExifTags.TAGS[k]
                #   exif_data = ('Tag: ' + str(k), 'Value: ' + str(v), 'Name: ' + tag_name)

                # 情報を入れるリストを用意する、後の処理の都合で、str型(文字型)に限定
                l1 = []# 撮影情報
                l2 = []# カメラやレンズの情報

                # タグ番号をキーとしてデータを取り出す

                # (1) カメラのメーカー、271 Make
                if 271 in primary_entry:
                    make = primary_entry[271].rstrip()
                    l2.append(make)

                # (2) カメラの機種名、272 Model
                if 272 in primary_entry:
                    model = primary_entry[272].rstrip()
                    l2.append(model)

                # その他の必要な情報は Exif IFD にある。タグ番号は、34665
                # get_ifd(34665) としてゲットする。辞書型
                if 34665 in primary_entry:
                    exif_ifd = primary_entry.get_ifd(34665)  # 34665, ExifOffset

                    # (3) 撮影日時 DateTimeDigitized
                    if 36867 in exif_ifd:
                        dt = exif_ifd[36867]
                        # 日付の文字列を iso format に変換
                        # replace(':', '-', 2) で年月日のコロンをマイナスに置換。最初の2個だけ。
                        dt = dt.replace(':', '-', 2)
                        l1.append(dt)

                    # (4) 絞り、FN.N
                    if 33437 in exif_ifd:
                        f = exif_ifd[33437]
                        # 絞り値は、小数点以下1位まで
                        f_value = round((f.numerator / f.denominator), 1)  # 分子÷分母、小数第二位を四捨五入
                        f_number = 'F' + str(f_value)
                        l1.append(f_number)

                    # (5) シャッタースピード、1/NNNsec
                    if 33434 in exif_ifd:
                        ss = exif_ifd[33434]
                        ss_value = round((ss.denominator / ss.numerator))  # 分子÷分母、小数第一位を四捨五入
                        shutter_speed = '1/'+ str(ss_value) + 'sec'
                        l1.append(shutter_speed)

                    # (6) 感度、ISONNN
                    if 34855 in exif_ifd:
                        iso = exif_ifd[34855]  # 感度
                        iso = 'ISO' + str(iso)
                        l1.append(iso)

                    # (7) レンズ
                    if 42036 in exif_ifd:
                        lens = exif_ifd[42036]
                        l2.append(lens)

                # 情報のリストを結合する
                l0.extend(l1)# l0 と l1 を結合したものを l0 とする
                l0.extend(l2)# 上の l0 と l2 を結合したものを l0 とする

                # リスト l0 の要素をコンマ区切りで結合する
                # 要素が空の場合は、左に詰める
                all_information = ', '.join(l0)# とりあえず多くの情報を取り出してみる
                # all_information = ', '.join(l1)# 撮影情報だけが必要な場合はこちら

                # このファイルの情報をリストに追加する、[ファイル名,撮影情報を表す文字]
                shooting_information.append([file_name, all_information])

    # csv ファイルに保存する
    # 名称は固定、上書き、このスクリプトと同じ場所に保存
    with open('./Shooting_Information.csv', 'w') as f:
        writer = csv.writer(f)
        writer.writerows(shooting_information)
        print(f.read)

if __name__ == '__main__':
    main()

Python が動作する環境があって、PILLOW がインストール済みであれば、上のスクリプトを標準テキストファイルにして拡張子を'py'にすれば、使えるんじゃないかな思います。

そんなこと面倒臭くてやってられないという人のために、有料部分にファイルを用意しました。

以前は外部ライブラリーに頼らないで作った

外部ライブラリーは便利だが、Raw 画像に対応していなかったので、写真のメタデータを読み取るルーチンを自分で作った。

この記事の話では、対象とする画像形式を TIFF と JPEG に絞ったので、外部ライブラリーを使って楽をした。

t.koba

ここから先は

122字 / 1ファイル

¥ 100

この記事が気に入ったらチップで応援してみませんか?