Pythonで写真の撮影日に合わせてファイル名を変更したい!

ノウハウ
スポンサーリンク

iphoneをPCに接続して「画像とビデオのインポート」で画像を移動させると、ファイル名が「iphone_ 001.JPG」、「iphone_ 002.JPG」のように連番でつけられてしまいました。
写真を管理するうえで非常に分かりにくい!!

というわけで、ファイル名を写真の撮影日でリネームすることにしました。
イメージは「20180615_004640.JPG」みたいに年月日_時分秒.拡張子のようにリネームすることにしました。

どうせならPythonで自動化したいなって思い、いろいろ調査しながらPythonスクリプトをつくりました。個人的な備忘録なので、あまりまとまりないですが、最後にサンプルコードを載せておくのでよろしければご参考にどうぞ。
なお、私のPC環境は以下です。

  • Windows10
  • Python 3.7.4

 

目次

 


 

撮影日を取得するにはどうすればいい?

撮影日を取得する方法をググりました。

 

すべての画像形式に適用できるPythonスクリプトを作りたいと思い、もう少し調査しました。

 

ということで、「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にリネーム後のフォーマットを指定できます。
  • 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」さんのサイトが、画像で説明されており分かりやすいです。

Windows版Pythonのインストール - python.jp
以下の手順で、Pythonのインストールを行います。 Python公式サイトから、Pythonパッケージをダウンロードします ダウンロードしたパッケージをインストールします。 PowerShellでPythonを実行するときに必要となる、ス...

 

広告

Pythonを勉強するなら、Udemyの「現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル」がオススメです!
※Udemyは技術的な講座を動画で受けられるサービスです。

 

以上!

コメント

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