
【Python写真の日付ごとにデータを整理(1)】写真から撮影年日を取得する。
こんにちは(@t_kun_kamakiri)
本日は、Pythonを使って写真の日付ごとにデータを整理するプログラムを書いていこうと思います。
デジタルカメラで撮影した写真(JPEG)には、画像以外にも多くの情報が記録されています。
●撮影日時にカメラの機種名
●レンズのF値やシャッター速度
●日付、更新日
などなど・・・・
これは、EXIF(Exchangeable image file format)という情報の記録に関するオープンな仕様です。電子情報技術産業協会(JEITA)により規格化され、2002年公開のEXIF 2.2が最新版となっています。
写真ファイルを右クリックして、プロパティを見ると、撮影日時の記載がありますね。
コーディングを行う前に、コーディングの流れを考えておきます。
●写真の撮影日を取得
●写真の撮影日から年度ごとのフォルダを作成する
●写真の撮影日から日付ごとのフォルダを作成する
●写真の撮影日と日付に応じてフォルダ移動を行う。
やりたいことのイメージは以下となります。
僕自身、今から調べながらコードを考えていくため、冗長な記事になってしまうことはご了承ください<(_ _)>
何編かに分けて記事を書いていきます。
いきなり完成したプログラムを見ても、どのように動いているのかを確認しながらの方が理解が深まると思うので、jupyter notebook(もしくはjupyter lab)を使ってプログラムを作成していきます。
【本日の内容】
写真から撮影年日を取得する。
【環境】
Windows10
Anaconda Python 3.8.3
必要なライブラリをインポート
ここでは、以下のライブラリをインポートします。
from PIL import Image
from PIL.ExifTags import TAGS
Pythonで画像関連を扱うライブラリではPILというものがありましたが、今はPILからフォークしたPython3対応のライブラリpillowがそれにあたります。
僕は、既にインストールされていたので、ここではインストールを必要としませんでしたが、インストールされていない方はpipからもpillowという名前でインストールができます。
細かい使い方は↓こちらの記事などが参考になりそうでですね。
TAGSが何か・・・print文で確認してみましょう。
from PIL.ExifTags import TAGS
print(TAGS)
TAGSは辞書型であることがわかります。
何やら「id(キー)」と「内容(値)」が関連付けされているようです。
ひとつ画像を開いてみる
# 画像ファイルを開く
im = Image.open('20191025_200630.jpg')
im
これで画像が開けるのですね。
超簡単です!
EXIF情報を得る
では、画像の情報を取得してみましょう。
# EXIF情報を得る
exif = im._getexif()
exif
このようにして簡単に写真の情報を取得できました。
赤で示した部分が、日付を表しているのがわかります。
でも、「id」と「情報」が辞書型で関連付けされているだけで、何の内容による情報がわかりません・・・・
そこで、idと関連した内容を取得するために、以下のようにidを取得してみます。
TAGS.get(36867)
そうすると内容が出てきました。
ということで、以下のようにして「id、内容、情報」の3つ取得することができるはずです。
# 一覧で表示
for id, value in exif.items():
print(id, TAGS.get(id), value)
exifは辞書型なので、items()メソッドを使うことで、辞書のキーと値を取得することができ、それをfor文でひとつひとつ取り出しています。
「内容と情報」だけ抽出する
idはどうでもよいので、内容と情報だけを取得するプログラムにします。
まずは、空の辞書型の変数を用意して、「TAGS.get(id)をキー」に「vaule」を値にします。
# 一覧で表示
dic_ = {}
for id, value in exif.items():
dic_[TAGS.get(id)] = value
dic_
これで、内容と情報が関連付けされた辞書型が完成しました。
撮影日のみを抽出する
先ほど撮影した辞書型の変数で必要になるのは、
DateTimeOriginal
の部分だけです。
ちなみにその他の日付情報は以下の内容だそうです。
'DateTime': '2019:10:25 20:06:30', # 画像ファイルの更新日
'DateTimeOriginal': '2019:10:25 20:06:30',# 撮影された日時
'DateTimeDigitized': '2019:10:25 20:06:30', # 画像がデジタルデータ化された日時
撮影日を取得するには、
dic_['DateTimeOriginal']
とすればよいです。
これで写真の撮影日時が取得できました。
年と月に分ける
最終的にやりたいことを考えると、ファイルを「年」「日付」で分けたいのでした。
↓やりたいことのおさらい・・・・
ということは、年と日付でわけるようにプログラムを変更します。
dic_['DateTimeOriginal'].split(' ')
空白で分けました。
このリストのindex 0だけを抜き出します。
dic_['DateTimeOriginal'].split(' ')[0]
これで年と日付が抽出されました。
ここからさらに、年と日付でわけます。
●まずは、年から・・・
year = dic_['DateTimeOriginal'].split(' ')[0].split(':')[0]
year
●そして、日付・・・
date = dic_['DateTimeOriginal'].split(' ')[0].split(':')[1] + '-' + dic_['DateTimeOriginal'].split(' ')[0].split(':')[2]
date
これで、写真の情報から「年」と「日付」を変数にすることができました(^^♪
全体をまとめる
from PIL import Image
from PIL.ExifTags import TAGS
# 画像ファイルを開く
im = Image.open('20191025_200630.jpg')
# 一覧で表示
dic_ = {}
for id, value in exif.items():
dic_[TAGS.get(id)] = value
year = dic_['DateTimeOriginal'].split(' ')[0].split(':')[0]
date = dic_['DateTimeOriginal'].split(' ')[0].split(':')[1] + '-' + dic_['DateTimeOriginal'].split(' ')[0].split(':')[2]
これでひとつの画像に対して「年」と「日付」の情報が取得でき、それを変数にすることができました。
次は、複数の写真から「年と日付の情報」を取得し、それを辞書型で整理するというのをしようと思います(^^)/
※ちなみに以下のようにコードを書いてもよいですね。
ひとつの写真の情報をすべて辞書型にする必要はなく、if文で撮影日だけを分岐させて日付データを取得するというのもありです。
from PIL import Image
from PIL.ExifTags import TAGS
# 画像ファイルを開く
im = Image.open('20191025_200630.jpg')
# 一覧で表示
# dic_ = {}
for id, value in exif.items():
if TAGS.get(id) == 'DateTimeOriginal':
date = value
year = date.split(' ')[0].split(':')[0]
date = date.split(' ')[0].split(':')[1] + '-' + dic_['DateTimeOriginal'].split(' ')[0].split(':')[2]
そうすると辞書型をわざわざ作成する必要がなくなります。
Python勉強するなら初学者用のサイトを作成しました。
Pythonを勉強しながら記事にまとめていったので、初学者の方は無料で学ぶことができます♪
僕がPyhonを一番初めに学んだときに買った参考書はこちらです。
一週間くらいで読めたので、初学者にもやさしい内容となっています(^^♪
Twitter➡@t_kun_kamakiri
ブログ➡宇宙に入ったカマキリ(物理ブログ)
ココナラ➡物理の質問サポートサービス