Exifデータを読む

はじめに

JPEG や HEIC などの写真データには Exif(Exchangeable image file format、エグジフ、エクシフ)という形式のメタデータが含まれている。写真編集ソフトで表示できる。昔からある ExifTool というツールで読み出すことができる。Homebrew を使っている Mac なら brew install exiftool で入る。また、ImageMagick の identify というコマンドで表示できる。ImageMagick は brew install imagemagick で入る。以下では特に撮影日時と GPS 位置情報について扱う。

例えば iPhone で大学の食堂で撮った写真 IMG_7949.HEIC は、Mac の Preview で見れば、次のようなメタ情報がある。

オリジナルの日時: 2022/10/18 11:38:32
高度: 7.52 m (24.66 ft)
緯度: 34° 44’ 43.08” N
経度: 136° 31’ 25.992” E

これに対して identify -verbose IMG_7949.HEIC と打ち込むと、137行にわたって詳細なメタ情報が出力される。この中で日時と GPS 情報は次の部分である:

    exif:DateTime: 2022:10:18 11:38:32
    exif:DateTimeDigitized: 2022:10:18 11:38:32
    exif:DateTimeOriginal: 2022:10:18 11:38:32
    exif:GPSAltitude: 66112/8797
    exif:GPSLatitude: 34/1, 44/1, 4308/100
    exif:GPSLatitudeRef: N
    exif:GPSLongitude: 136/1, 31/1, 2599/100
    exif:GPSLongitudeRef: E

同じことを ExifTool でやってみると、116行のメタ情報が出力される。日時と GPS 情報は次のようになっている:

Create Date                     : 2022:10:18 11:38:32.937+09:00
Date/Time Original              : 2022:10:18 11:38:32.937+09:00
Modify Date                     : 2022:10:18 11:38:32+09:00
GPS Altitude                    : 7.5 m Above Sea Level
GPS Latitude                    : 34 deg 44' 43.08" N
GPS Longitude                   : 136 deg 31' 25.99" E

ExifTool にオプション -c "+%.6f" をつければ次のような10進表示になる:

GPS Latitude                    : +34.745300 N
GPS Longitude                   : +136.523886 E

得られた位置情報はGoogleマップで https://maps.google.com/maps?q=34.7453,136.523886 のように指定できる。GPS の誤差のため、実際の一と若干ずれている。

PythonのExifRead(EXIF.py)

Python で Exif が扱えるライブラリはたくさんある。例えば ExifRead は GitHub では EXIF.py という名前で開発されている。2022-05-09 に 3.0.0 が出た。ところが HEIC ファイルでエラーになるという指摘がずっと放置されている。これを入れるなら、次のようにして 3.0.0 未満(2.3.2)をインストールするほうがよさそうだ:

pip install --upgrade 'exifread<3'

これをインストールすると、EXIF.py というコマンドが使えるようになる。EXIF.py IMG_7949.HEIC の出力は65行で、日時と位置情報の部分は次の通り:

EXIF DateTimeDigitized (ASCII): 2022:10:18 11:38:32
EXIF DateTimeOriginal (ASCII): 2022:10:18 11:38:32
GPS GPSAltitude (Ratio): 66112/8797
GPS GPSLatitude (Ratio): [34, 44, 1077/25]
GPS GPSLatitudeRef (ASCII): N
GPS GPSLongitude (Ratio): [136, 31, 2599/100]
GPS GPSLongitudeRef (ASCII): E

Python から使うには次のようにする:

import exifread

with open("IMG_7949.HEIC", "rb") as f:
    tags = exifread.process_file(f)
tags
{'Image Make': (0x010F) ASCII=Apple @ 146,
 'Image Model': (0x0110) ASCII=iPhone SE (3rd generation) @ 152,
……中略……
 'GPS GPSLatitudeRef': (0x0001) ASCII=N @ 1682,
 'GPS GPSLatitude': (0x0002) Ratio=[34, 44, 1077/25] @ 1774,
 'GPS GPSLongitudeRef': (0x0003) ASCII=E @ 1706,
 'GPS GPSLongitude': (0x0004) Ratio=[136, 31, 2599/100] @ 1798,
 'GPS GPSAltitudeRef': (0x0005) Byte=0 @ 1730,
 'GPS GPSAltitude': (0x0006) Ratio=66112/8797 @ 1822,
……中略……
 'EXIF DateTimeOriginal': (0x9003) ASCII=2022:10:18 11:38:32 @ 622,
 'EXIF DateTimeDigitized': (0x9004) ASCII=2022:10:18 11:38:32 @ 642,
……後略……

この特定の項目を取り出すには次のようにする:

tags['EXIF DateTimeOriginal']
(0x9003) ASCII=2022:10:18 11:38:32 @ 622
tags['EXIF DateTimeOriginal'].printable
'2022:10:18 11:38:32'
a = eval(tags['GPS GPSLatitude'].printable)
a[0] + (a[1] + a[2]/60) / 60
34.7453

日時については、'Image DateTime''EXIF DateTimeOriginal''EXIF DateTimeDigitized' の三つが格納されているようだ。