0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PythonでiPhone撮影の.heic写真を撮影日付でリネームしJPEGで保存

Last updated at Posted at 2025-02-02

背景

私は、夫婦のそれぞれのiPhoneで撮影した写真をネットプリントでプリントアウトしアルバム整理をしています。
ただし私が使っているネットプリント・サービスはファイル名ごとにソートされ、夫婦で共有した写真を混ぜるとファイル名がバラバラなので、日付がバラバラで並んできて不便でした。また、写真の裏にファイル名のみが記載されるので、日付をわかるようにした上で、日付ごとに並んでプリントしたいと考えていました。

また、iPhoneで写真撮影をすると、デフォルトではHEICという形式で保存されます。HEICの詳細な説明は省きますが、このファイルをWindowsの標準で表示しようとすると厄介で扱いにくいためJPEGで保存してWindows上で表示したいと思っていました。(ただし画質は多少犠牲にする前提)

やりたいこと

  • iPhoneで撮影した写真のファイル名を撮影日付にしたい
  • iPhone撮影にて標準で保存されるHEICファイルを、JPEGファイルとして保存し直したい

やること

  • HEICファイルを読み込み (pillow-heifを使う)
  • 撮影日時を抜き出す (写真に埋め込まれたExifの情報を抽出)
  • 撮影日時をファイル名にする (Exifの撮影日時をdatetimeにして、自分の好きな形式にする)
  • JPEGに変換して保存する (PillowでJPEG保存)

前提

  • Windows (他のOSでも動くと思うけど確かめてません)
  • iPhone撮影の写真がWindows上の特定フォルダに保存されている
  • Pythonを使う (Jupyter Notebookでやりました)

手順

ライブラリインストール

pipでpillowとpillow-heifをインストールします。

$ pip install pillow pillow-heif

pillow-heifは、pillowでHEIC形式の画像を扱うことができるライブラリです。HEICのまま様々な処理ができますが、pillow-heifを利用して画像ファイルを読み込むだけで、意識することなく通常のPIL.Imageオブジェクトのように扱うことができるようになります。

Pythonコード

少し行数(ステップ)を長く書いていますが、ステップごとのわかりやすさ/読みやすさ重視の記述をしています。
詳しくコメントをつけていますが、ExifのDictについては後述します。

HEICファイルを読み込み、撮影日付でリネームしJPEGで保存
from datetime import datetime
from pathlib import Path

from PIL import Image
from pillow_heif import HeifImagePlugin

# HEIC形式の写真が保存されているフォルダを指定
photo_dir = Path('C:\\my_photo')
# リネーム後の出力先フォルダを作成しておく
out_dir = photo_dir / Path('.\\rename')
out_dir.mkdir(exist_ok=True, parents=True)

# フォルダに保存されている.heicまたは.jpgファイルをリスト化(jpegで保存された写真も扱っていたため)
files = [*photo_dir.glob('*.heic'), *photo_dir.glob('*.jpg')]

for i, file in enumerate(files, 1):
    # HEICファイルをImageオブジェクトとして読み込み
    im = Image.open(file)
    # 埋め込まれたExif情報を読み込む(Exifオブジェクトを取得※後述)
    p_ex = im.getexif()
    p_len = len(files)
    try:
        # Exifから撮影日時を取得(ExifオブジェクトからDateTimeを取得※後述)
        p_date_str = p_ex[ExifTags.Base.DateTime]
        # Exifの日付形式から、datetimeオブジェクトに変換
        tm_dt = datetime.strptime(p_date_str, "%Y:%m:%d %H:%M:%S")
        # 日付-時刻という形式の文字列にする
        tm_str = tm_dt.strftime('%Y%m%d-%H%M%S')
        # 日付-時刻.jpgの拡張子をつけたファイル名とする
        f_name = tm_str + '.jpg'
        print(f'{i} / {p_len}: {file.name} -> {f_name}')
        # 出力フォルダにファイル名を加え、出力先のフルパスを作成する
        out_path = out_dir / f_name
        # JPEGで保存する。Exif情報も埋め込んでおく
        im.save(out_path, quality=80, exif=p_ex)
    except Exception as e:
        # Exifが埋め込まれてないファイルなどがあれば、エラーとして出力して処理は継続する
        print(f'Error: {file.name}, {e}')

Exifから撮影日時の取得について

PillowとExifについて知らない中でリファレンスを見て初めて知ったのでメモとして残しておきます。

PillowのImageオブジェクトの中には、Exifオブジェクトが存在します。

このExifオブジェクトから、EnumであるExifTagsを使って画像に埋め込まれたExifの各項目を抽出可能になっています。

今回は撮影日時なので、PIL.ExifTags.Baseのsourceに記載されているDateTimeを指定します。

Exifの撮影日付を抽出する部分
p_ex = im.getexif()
p_date_str = p_ex[ExifTags.Base.DateTime]
print(p_date_str)
# 2024:09:16 13:07:05

今回やりたいこととは異なりますが、位置情報はPIL.ExifTags.GPSで取得できるようになっています。

Exifは規格化されているものの、すべてのタグの情報がすべてのカメラで保存されるわけではないので、iPhoneから取得できる情報は限られていますが、無事撮影日付を取得することができました。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?