2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

写真の撮影日時を超超超いい感じに修正するスクリプト

Last updated at Posted at 2021-04-11

ざっくり

写真を Amazon Photos などのクラウドサービスにアップした際、
撮影日時が入っていなかったりズレがある写真はあらぬ位置に表示されてしまいます。
before.png
ということで、撮影日時をいい感じに修正するスクリプトを書きました。

実行後はこんな感じ。
after.png

ついでに元に戻したい時のためのスクリプトと記録した変更履歴を削除するスクリプトも書きました。

スクリプトの解説

exif_manager.py

下記スクリプトで利用するクラスを定義したもの。
ExifTool (https://exiftool.org/) を利用した EXIF 情報の更新を行うので、
ExifTool のインストールが必要。
Macの場合はbrewで簡単インストール。

brew install exiftool

photo_daytime_fixer.py

日時をいい感じに修正するスクリプト。

処理

  1. 修正を行うフォルダを指定してスクリプトを実行

    $ python3 photo_datetime_fixer.py <対象フォルダ>
    
  2. 指定した指定したフォルダ内のファイルを名前順で確認していく

  3. 撮影日時 (DateTimeOriginal) の整合性が前後と取れていないファイルを対象に EXIF 情報を更新する

    • DateTimeOriginal の更新
      • 前後のファイルの撮影日時の間の日時(年〜秒)とする
      • 対象ファイルが複数の場合は均等に配分する
      • 1番目のファイルについてはなにもしない
      • 最後のファイル(たち)が対象の場合は直前の整合性が取れているファイルの日時に1秒ずつ足した日時に設定
    • UserComment の追記
      • DateTimeOriginal の更新内容を以下の形式で記録する
        FixedDateTimeOriginal_<このスクリプトを実行したUNIX時間>[<元の日時> -> <変更後の日時>]
        
      • このコメントは後述の photo_daytime_restorer で利用する
      • もともとコメントが存在する場合には半角スペース区切りで追記

動作例

実行前

ファイル名 DateTimeOriginal UserComment
0.JPG 2021:04:01 00:00:00 test0
1.JPG test1
2.JPG 1999:01:01 00:00:00 test2
3.JPG 2021:04:01 03:06:09 test3
4.JPG 2021:04:01 04:08:12 test4

実行

$ python3 photo_datetime_fixer.py /xxx/test
+-------------------------+
| Photo Date & Time Fixer |
+-------------------------+
Target Dir: /xxx/test
Fix ID: 1618139631

0.JPG: Skip: No data before.
1.JPG: Need to fix.
2.JPG: Need to fix.
3.JPG: OK.
Fix!
  1.JPG: Fixed:  -> 2021:04:01 01:22:03
  2.JPG: Fixed: 1999:01:01 00:00:00 -> 2021:04:01 02:44:06
4.JPG: OK.

+-----------+
| 🍻Fixed🍻 |
+-----------+

実行後

ファイル名 DateTimeOriginal UserComment
0.JPG 2021:04:01 00:00:00 test0
1.JPG 2021:04:01 01:02:03 test1 FixedDateTimeOriginal_1618139631[ -> 2021:04:01 01:02:03]
2.JPG 2021:04:01 02:04:06 test2 FixedDateTimeOriginal_1618139631[1999:01:01 00:00:00 -> 2021:04:01 02:04:06]
3.JPG 2021:04:01 03:06:09 test3
4.JPG 2021:04:01 04:08:12 test4

photo_daytime_restorer.py

日時を元に戻すスクリプト。

処理

  1. 修正を行うフォルダと photo_daytime_fixer を実行したUNIX時間を指定してスクリプトを実行

    $ python3 photo_datetime_restorer.py <対象フォルダ> <photo_daytime_fixerを実行したUNIX時間>
    
  2. UserComment を参照することで対象ファイルを探し、EXIF 情報を更新する

    • DateTimeOriginal の更新
      • 元の日時に更新
    • UserComment の追記
      • DateTimeOriginal の更新内容を以下の形式で記録する
        RestoredDateTimeOriginal_<このスクリプトを実行したUNIX時間>[<元の日時> -> <変更後の日時>]
        
      • もともとコメントが存在する場合には半角スペース区切りで追記

動作例

実行前

ファイル名 DateTimeOriginal UserComment
0.JPG 2021:04:01 00:00:00 test0
1.JPG 2021:04:01 01:02:03 test1 FixedDateTimeOriginal_1618139631[ -> 2021:04:01 01:02:03]
2.JPG 2021:04:01 02:04:06 test2 FixedDateTimeOriginal_1618139631[1999:01:01 00:00:00 -> 2021:04:01 02:04:06]
3.JPG 2021:04:01 03:06:09 test3
4.JPG 2021:04:01 04:08:12 test4

実行

$ python3 photo_datetime_restorer.py test 1618139631
+----------------------------+
| Photo Date & Time Restorer |
+----------------------------+
Target Dir: test
Fix ID: 1618139631
Restore ID: 1618140405

0.JPG: Skip.
1.JPG: Restore.
  2021:04:01 01:02:03 -> 
2.JPG: Restore.
  2021:04:01 02:04:06 -> 1999:01:01 00:00:00
3.JPG: Skip.
4.JPG: Skip.

+-------------+
| 🍻Restored🍻 |
+-------------+

実行後

ファイル名 DateTimeOriginal UserComment
0.JPG 2021:04:01 00:00:00 test0
1.JPG 2021:04:01 01:02:03 test1 FixedDateTimeOriginal_1618139631[ -> 2021:04:01 01:02:03] RestoredDateTimeOriginal_1618140405[2021:04:01 01:02:03 -> ]
2.JPG 2021:04:01 02:04:06 test2 FixedDateTimeOriginal_1618139631[1999:01:01 00:00:00 -> 2021:04:01 02:04:06] RestoredDateTimeOriginal_1618140405[2021:04:01 02:04:06 -> 1999:01:01 00:00:00]
3.JPG 2021:04:01 03:06:09 test3
4.JPG 2021:04:01 04:08:12 test4

photo_daytime_forgetter.py

日時の更新履歴を消すスクリプト。

処理

  1. 修正を行うフォルダと photo_daytime_fixer もしくは photo_daytime_restorer を実行したUNIX時間を指定してスクリプトを実行

    $ python3 photo_datetime_restorer.py <対象フォルダ> <photo_daytime_fixer/restorerを実行したUNIX時間>
    
  2. UserComment を参照することで対象ファイルを探し、EXIF 情報を更新する

    • UserComment の更新
      • コメント中から指定した実行についての記述のみを削除する

動作例

実行前

ファイル名 UserComment
0.JPG test0
1.JPG test1 FixedDateTimeOriginal_1618139631[ -> 2021:04:01 01:02:03] RestoredDateTimeOriginal_1618140405[2021:04:01 01:02:03 -> ]
2.JPG test2 FixedDateTimeOriginal_1618139631[1999:01:01 00:00:00 -> 2021:04:01 02:04:06] RestoredDateTimeOriginal_1618140405[2021:04:01 02:04:06 -> 1999:01:01 00:00:00]
3.JPG test3
4.JPG test4

実行

$ python3 photo_datetime_forgetter.py test 1618139631
+-----------------------------+
| Photo Fix/Restore Forgetter |
+-----------------------------+
Target Dir: test
Fix/Restore ID: 1618139631

0.JPG: Skip.
1.JPG: Forget.
    test1 FixedDateTimeOriginal_1618139631[ -> 2021:04:01 01:02:03] RestoredDateTimeOriginal_1618140405[2021:04:01 01:02:03 -> ]
 -> test1 RestoredDateTimeOriginal_1618140405[2021:04:01 01:02:03 -> ]
2.JPG: Forget.
    test2 FixedDateTimeOriginal_1618139631[1999:01:01 00:00:00 -> 2021:04:01 02:04:06] RestoredDateTimeOriginal_1618140405[2021:04:01 02:04:06 -> 1999:01:01 00:00:00]
 -> test2 RestoredDateTimeOriginal_1618140405[2021:04:01 02:04:06 -> 1999:01:01 00:00:00]
3.JPG: Skip.
4.JPG: Skip.

+---------------+
| 🍻Forgotten🍻 |
+---------------+

実行後

ファイル名 UserComment
0.JPG test0
1.JPG test1 RestoredDateTimeOriginal_1618140405[2021:04:01 01:02:03 -> ]
2.JPG test2 RestoredDateTimeOriginal_1618140405[2021:04:01 02:04:06 -> 1999:01:01 00:00:00]
3.JPG test3
4.JPG test4

留意事項

  • 対象のファイルの EXIF 情報に元から SubSecDateTimeOriginal が含まれていた場合は年〜秒までは一緒に更新される
    • SubSecDateTimeOriginal には ms 以下の時間やタイムゾーンが書かれている
    • 年〜秒以外の部分はオリジナルのままになる
  • 対象フォルダ内に EXIF 情報を更新できないファイル(ExifTool のサポート外、もしくは書き込み権限なし)のファイルがあった場合には、そのファイルについては何もしない
    • ただし、複数ファイルを一気に更新する際の時間間隔計算の分母にはカウントされる
  • 対象のはずなのにうまく動作しないファイルもあった
    • サイズが小さいファイル
      • 大昔のiPhoneのスクショ
      • ガラケー時代の遺産ことデコ文字のファイル
    • 他にもあるかも
  • PNG は EXIF 情報が正しく更新できた場合でも、Amazon Photos では日付なしに分類されてしまう
    • 悲しい
  • 仕様上、大量にファイルがあり前後の正しいファイルの撮影時間の差が小さいと間隔が1秒未満になってしまい、正しい結果が得られない
    • SubSecDateTimeOriginal でなんとかしようとしましたが、ファイルによってタイムゾーンの表記があったりなかったりだったので断念
    • まあ、あまり起こり得ない & 起こってもあまり影響はない想定

余談

  • Google フォトの無料枠が終了するということで Amazon Photos に乗り換えようとしたところ、順序の狂い方が Google のときより酷い気がしてすごくムカついたので2日くらいでバーっと書きました。
    • なので日時を示す EXIF タグのうち、Amazon Photos で日時として認識されているっぽい DateTimeOriginal を更新することにしました。
    • あまり Python に触ってこなかった人生ですが今どきそれはさすがにエンジニアとして、、、ということで Python で。
    • 最初は PIL (https://pillow.readthedocs.io/en/stable/#) を使おうとしましたが、HEIC に対応指定なさそうだったので断念。ExifToolを利用することに。
      • ならシェルスクリプトでよくね感もありましたがせっかくなので、、、
    • Python 初心者なので超拙いです多分、レビューお待ちしております。
  • これ使っても Amazon Photos にアップ済みのファイルは修正できない
    • 一括削除しようとしましたがいつの間にかできない仕様に、、、
    • 3000件までなら一括選択できるスクリプトを書かれている方がいらっしゃったのでそれを利用しました。
      https://qiita.com/M_Kagawa/items/9b7dc3fa310a0170b6b2
  • GitHubプライベートアカウント&Qiitaへの初投稿なのでお手柔らかに。
    • 勝手がアレ。
    • 誤字脱字もめちゃくちゃありそう。

以上、あざした!

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?