はじめてのPythonプログラミング

Python
作成したアプリのスクリーンショット
ずいぶん以前にVBAで作成した写真集計くん+ for Windowsの機能を一部抜粋して作った

なんだか書籍のタイトルみたいですが本当の話なんだからしょうがないですこんにちは。

ここ2週間弱ほどプログラミング言語のPythonの学習に費やしていました。ちょこちょこ、ゴニョゴニョやって、GUIインターフェイスを持ったものとCUIの自分用ツールができました。

最初はMacかiPhoneのアプリでも作成して大儲けしてやろうwと思って始めたのですが、どうもやっていくうちにPythonではそういうのはちょっとアレな感じだということがわかってきました。そういうアプリを作るならやっぱりクソめんどくさそうですがXcodeとSwiftを使うべきなんだなということがわかりました。

そしてPythonで作るなら、Webアプリか自分で使う用のちょっとしたツールがいいんじゃないかという結論に至りました。

というわけで自分用ツール「フォルダ内のすべての写真のExif情報を抜き出して一覧を作成しようツール」を作ったんですが、結構使えるので皆さんもどうですかって記事。

Pythonコード

まあ何せはじめてでスッタモンダしながら作ったものですから、多分に素人臭いコードですがご勘弁ください。

# coding: UTF-8
# ライブラリ読み込み
import os
import sys
import csv
import pathlib
from datetime import datetime
from PIL import Image
from PIL.ExifTags import TAGS

# イメージファイルからexif情報の辞書を取得する関数
# 戻り値は  辞書型
#           Exif 情報がない場合には空の辞書
def getExifDic(img_file):
    im = Image.open(img_file)
    try:
        exif = im._getexif()
    except AttributeError:
        pass

    exif_table = {}
    for tag_id, value in exif.items():
        tag = TAGS.get(tag_id, tag_id)
        exif_table[tag] = value

    return exif_table


# コマンドライン引数を取得
# 引数の数を数える
args = sys.argv
num_args = len(args)

# 日付時間文字列を取得し、csvファイルに付加する
dt_now = datetime.now()
dt_str = dt_now.strftime('%Y%m%d%H%M%S')
outpath = "ExifsList-" + dt_str + ".csv"

# 引数が足りなかったり多かったりしたら処理を中断
# csvファイルのパスを整形
if num_args == 1 or num_args > 3:
    print("<<ERROR>> Wrong args.")
    print("(ex.) python3 (path/)create_exif_list.py [ScanFolderPath] (ExifListSavePath)")
    sys.exit()
elif num_args == 3:
    outpath = args[2] + "/" + outpath

counter = 0
# csvファイルに書き込むexif情報のキーを決める
exif_keys = ["FileFullPath","FileFolderPath","FileName","ExifVersion","CompressedBitsPerPixel","DateTimeOriginal","DateTimeDigitized","ShutterSpeedValue","ApertureValue","BrightnessValue","ExposureBiasValue","MaxApertureValue","MeteringMode","LightSource","Flash","FocalLength","ColorSpace","ExifImageWidth","ExifImageHeight","FocalPlaneXResolution","FocalPlaneYResolution","FocalPlaneResolutionUnit","SubjectDistanceRange","Make","Model","SensingMethod","Orientation","FileSource","ExposureTime","ExifInteroperabilityOffset","XResolution","FNumber","SceneType","Copyright","YResolution","ExposureProgram","CustomRendered","ISOSpeedRatings","ResolutionUnit","ExposureMode","FlashPixVersion","Software","DateTime","SceneCaptureType","ExifOffset","YCbCrPositioning"]

# csvファイルを準備する
csv_file = open(outpath,'w')
writer = csv.DictWriter(csv_file,fieldnames=exif_keys, extrasaction='ignore')
writer.writeheader()

# 与えられたフォルダ内をスキャンしてjpgファイルのみを処理していく
for folders, subfolders, files in os.walk(args[1]):
    if files != None:
        for f in files:
            if ".jpg"  in f or ".JPG" in f:
                counter += 1
                p1 = str(folders) + "/" + str(f)
                p2 = pathlib.Path(p1)
                fullpath = p2.resolve()
                dirpath = os.path.dirname(fullpath)
                filename = os.path.basename(fullpath)
                print(counter)
                print("writing: " + filename)
                dict1 = {'FileFullPath':fullpath,'FileFolderPath':dirpath,'FileName':filename}
                # jpgファイル中にexif情報が存在しない場合はエラーを表示して
                # ファイルパスのみを書き出す
                try:
                    dict2 = getExifDic(fullpath)
                except AttributeError as e:
                    print("<<ERROR>> AttrE:" + str(e))
                    pass
                else:
                    dict1.update(dict2)
                # 書き込むべきexifキーが存在しないときは飛ばす
                try:
                    writer.writerow(dict1)
                except ValueError as e:
                    print("<<ERROR>> ValueE:" + str(e))
                    pass

print("=========")
print("Finished.")
print("=========")

csv_file.close()

上記コードを任意の名前で保存します。一応私は「create_exif_list.py」という名前で使っています。

使い方

使用するにはPython3系がインストールされていることが前提になります。もちろんターミナルから実行します。
コマンド書式は

$ python3 (path/)create_exif_list.py ScanFolderPath [ExifListSavePath]

となります。ExifListSavePath は省略可能です。省略した場合はカレントディレクトリにcsvファイルが吐き出されます。下に例をあげます。バックスラッシュの入ったところはスペースをエスケープしています。見にくいですね。はい、すみません。

第2引数を省略した場合の例
第2引数を指定した場合の例

あとはreturnキーを押すだけです。つらつらと画面表示が流れていくのをのんびりと眺めていれば良いというわけです。

実行結果

ためしに6097ファイルほど処理してみたのですが多分1分10秒ほどで終わりました。こんな感じです。

実行直後の画面
作成されたcsvファイルのQuickLook その1
作成されたcsvファイルのQuickLook その2

こんな感じで記録のない項目は空欄になります。あとはエクセルに読み込んだりしていじくり回してみるのも面白いかもです。

これはなかなか使いでがあるなーと思っていただけたらどうぞ。

コメント

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