iphoneをPCに接続して「画像とビデオのインポート」で画像を移動させると、ファイル名が「iphone_ 001.JPG」、「iphone_ 002.JPG」のように連番でつけられてしまいました。
写真を管理するうえで非常に分かりにくい!!
というわけで、ファイル名を写真の撮影日でリネームすることにしました。
イメージは「20180615_004640.JPG」みたいに年月日_時分秒.拡張子のようにリネームすることにしました。
どうせならPythonで自動化したいなって思い、いろいろ調査しながらPythonスクリプトをつくりました。個人的な備忘録なので、あまりまとまりないですが、最後にサンプルコードを載せておくのでよろしければご参考にどうぞ。
なお、私のPC環境は以下です。
- Windows10
- Python 3.7.4
目次
撮影日を取得するにはどうすればいい?
撮影日を取得する方法をググりました。
- iphoneの画像形式は「jpeg」、「png」、「heic」があるみたい。
- jpeg画像の撮影日については「exif」情報を使用すれば取れそう。
- 「exif」情報はpythonのライブラリ「PIL」の「PIL.ExifTags」を使えば簡単に取得できそう。
- しかし、PNG形式には「exif」情報がない。。。
- 実際にiphoneで撮影したPNGファイルを確認したが、「exif」情報がなかった。
- 補足「jpeg,png,heicのExlifを確認してみる」を参考
すべての画像形式に適用できるPythonスクリプトを作りたいと思い、もう少し調査しました。
- PNGでも、ファイルの更新日を使えば、撮影日を取得できそう。
- コピーした場合、コピー先のデータは「更新日」はキープされますが、「作成日」「アクセス日」はコピーしたタイミングの日時に変わります。
- 更新日はPythonの標準ライブラリ「os」を使えば取得できそう。
ということで、「jpeg」、「png」、「heic」の画像形式に対して、ファイルの更新日を使えば、撮影日が取得できそうだということが分かりました。
※写真をPC上で加工したりして上書きしてしまった場合は、更新日=上書き日になってしまうため、この方法は使えませんのでご注意ください。
サンプルコード
ファイルの更新日からファイル名をリネームするPythonスクリプトを張っておきます。
※写真をPC上で加工したりして上書きしてしまった場合は、更新日=上書き日になってしまうため、この方法は使えませんのでご注意ください。
# 間違っていたらご指摘くださると助かります。
import glob, os, datetime,locale
##### パラメータ指定
# 画像ファイルのフォーマット
# 書式コードの参考:
# https://docs.python.org/ja/3/library/datetime.html#strftime-and-strptime-format-codes
FORMAT = '%Y%m%d_%H%M%S'
# 画像ファイルを検索するフォルダを指定
TARGET_DIRS = {
'C:/work/sample/',
}
# 同時刻(秒スケール)に撮影した画像の最大数(これ以上多かったらエラーとする)
MAX_NUM_ON_SAME_TAKEN_TIME = 100
##### 関数
def RenameToTokenDate(targetFilePath):
ret = False
message = ''
# ファイルチェック
try:
if not os.path.isfile(targetFilePath):
message = 'RenameToTokenDate()にファイル以外は指定できません。'
return (ret, message)
# ファイルの更新時刻,ディレクトリ名,拡張子を取得
statinfo = os.stat(targetFilePath)
dt_mtime = datetime.datetime.fromtimestamp(statinfo.st_mtime).strftime(FORMAT)
file_dir = os.path.dirname(targetFilePath)
filename, ext = os.path.splitext(os.path.basename(targetFilePath))
except Exception as e:
print(e)
message = 'ファイルチェックで予期せぬエラーが発生しました。'
return (ret, message)
# ファイル名変更
try:
file_index = ''
for i in range(MAX_NUM_ON_SAME_TAKEN_TIME):
renamedFilePath = file_dir + '/' + dt_mtime + file_index + ext
if( not os.path.exists(renamedFilePath) ):
os.rename(targetFilePath, renamedFilePath)
break
file_index = '_' + str(i+1)
else:
message = '同時刻(秒スケール)に撮影した画像がMAX_NUM_ON_SAME_TAKEN_TIME({0})\
を超えました。'.format(MAX_NUM_ON_SAME_TAKEN_TIME)
return (ret, message)
except Exception as e:
print(e)
message = 'ファイル名変更で予期せぬエラーが発生しました。'
return (ret, message)
ret = True
message = 'ファイル名の変更に成功しました。変更前:{0}, 変更後:{1}'\
.format(targetFilePath, renamedFilePath)
return (ret, message)
##### メイン処理
if __name__ == '__main__':
##### 初期処理
# ロケール情報の設定
locale.setlocale(locale.LC_CTYPE, "Japanese_Japan.932")
##### 画像ファイルを一つずつ、更新日からファイル名をリネーム
for targetDir in TARGET_DIRS:
for targetFilePath in glob.glob(targetDir+'/**', recursive=True):
# ファイル以外は飛ばす
if not os.path.isfile(targetFilePath): continue
# ファイル名をリネーム
print('##### {0}のファイル名変更開始...'.format(targetFilePath))
ret, message = RenameToTokenDate(targetFilePath)
if( ret ):
print('結果: 成功')
else:
print('結果: 失敗')
print('詳細: {0}'.format(message))
FORMAT
にリネーム後のフォーマットを指定できます。- 書式は「strftime() と strptime() の書式コード」を参照してください。
TARGET_DIRS
でリネームしたいファイルが格納されたフォルダを指定してください。配下のフォルダは再帰的に検索します。
サンプルコードを試してみる
簡単なテスト環境でサンプルコードを実行してみました。
テスト環境
テスト環境は以下を想定します。
【ディレクトリ構成】
Cドライブ配下にworkフォルダを作成し、その配下のsampleに画像ファイルを格納しています。
「RenameToTakenDate.py」には上記サンプルコードが記載されています。
C:\WORK
│ RenameToTakenDate.py
│
└─sample
heic_sample.heic
jpg_sample.jpg
png_sample.png
sametime1.png
sametime2.png
【画像ファイル】
各画像ファイルの更新日は以下となっています。
- heic_sample.heic
- 更新日: 2019年1月26日、19:19:17
- jpg_sample.jpg
- 更新日: 2018年7月29日、15:05:55
- png_sample.png
- 更新日: 2018年6月15日、0:46:40
- sametime1.png
- 更新日: 2021年1月11日、23:04:59
- sametime2.png
- 更新日: 2021年1月11日、23:04:59
サンプルコードの実行
コマンドプロンプトで以下のコマンドを実行します。
> cd C:\work
> python RenameToTakenDate.py
サンプルコード実行結果
リネームが成功すると以下のようなログがコマンドプロンプト上に表示されます。
C:\work>python RenameToTakenDate.py
##### C:/work/sample\heic_sample.heicのファイル名変更開始...
結果: 成功
詳細: ファイル名の変更に成功しました。変更前:C:/work/sample\heic_sample.heic, 変更後:C:/work/sample/20190126_191917.heic
##### C:/work/sample\jpg_sample.jpgのファイル名変更開始...
結果: 成功
詳細: ファイル名の変更に成功しました。変更前:C:/work/sample\jpg_sample.jpg, 変更後:C:/work/sample/20180729_150555.jpg
##### C:/work/sample\png_sample.pngのファイル名変更開始...
結果: 成功
詳細: ファイル名の変更に成功しました。変更前:C:/work/sample\png_sample.png, 変更後:C:/work/sample/20180615_004640.png
##### C:/work/sample\sametime1.pngのファイル名変更開始...
結果: 成功
詳細: ファイル名の変更に成功しました。変更前:C:/work/sample\sametime1.png, 変更後:C:/work/sample/20210111_230459.png
##### C:/work/sample\sametime2.pngのファイル名変更開始...
結果: 成功
詳細: ファイル名の変更に成功しました。変更前:C:/work/sample\sametime2.png, 変更後:C:/work/sample/20210111_230459_1.png
png、jpeg、heicのどの画像形式でも撮影日にリネームすることができました!
また、同じ時刻に撮影したファイルも「_*」でインデントされることも確認できました。
C:\WORK
│ RenameToTakenDate.py
│
└─sample
20180615_004640.png
20180729_150555.jpg
20190126_191917.heic
20210111_230459.png
20210111_230459_1.png
補足1 jpeg,png,heicのExlifを確認してみる
「Exifチェッカー」を使ってjpeg、png、heic形式の画像ファイルからExlif情報が取れるか確認してみました。
【結果】
- jpeg ⇒ Exlif情報を取得できた。
- png ⇒ Exlif情報を取得できなかった。
- heic ⇒ Exlif情報を取得できなかった。
補足2 Pythonをインストールするのに参考になりそうなサイト
日本のPythonコミュニティ「python.jp」さんのサイトが、画像で説明されており分かりやすいです。
広告
Pythonを勉強するなら、Udemyの「現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル」がオススメです!
※Udemyは技術的な講座を動画で受けられるサービスです。
以上!
コメント