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 で 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'
の三つが格納されているようだ。