moshimore Knowledge

アプリ開発・紹介とメモ書き、日々の日記。

スマホやデジカメで撮影した写真に埋め込まれるExifについて

f:id:moshimore:20190212025541j:plain
写真ファイルの更新日時修正ツールをAndroidアプリでリリースしたところ、ファイルの更新日時(タイムスタンプ)だけではなく、Exifの撮影日時も修正したいという意見を頂きました。
せっかくなので、そのうちに修正できる機能を追加していきたいと思います。
その前にAndroidアプリの開発において、必要なExifの仕様について分かりやすく纏めてみました。

リリース済みのアプリについて

リリース済みの更新日時修正ツールは、Exifの撮影日時や変更日時の修正ではなく、あくまでファイルの更新日時(タイムスタンプ)の修正用ツールです。

knowledge.moshimore.jp

主な機能としては、ファイルのExifの撮影日時を取得して、その日時がファイルの更新日時と異なっていた場合、ファイルの更新日時をExifの撮影日時に合わせることができます。
現時点のアプリ(バージョン1.0.0)では、撮影日時としてExifのDateTimeOriginalタグのデータを取得しています。

Androidアプリで、このDateTimeOriginalタグのデータはとても簡単で方法で取得することができます。
但し、minSdkVersionは、24からになりますので、そこだけ注意が必要です。

ExifInterface exifInterface = new ExifInterface(targetFilePaht);
String dateTimeOriginal = exifInterface.getAttribute(ExifInterface.TAG_DATETIME_ORIGINAL);

knowledge.moshimore.jp

6種類のタグについて

この修正ツールでは、DateTimeOriginalタグ(ExifInterface.TAG_DATETIME_ORIGINAL)を使って写真の撮影日時を取得していますが、実は、日時に関する情報には6種類のタグが用意されています。

Log.d("TAG_DATETIME", exifInterface.getAttribute(ExifInterface.TAG_DATETIME));
Log.d("TAG_DATETIME_ORIGINAL", exifInterface.getAttribute(ExifInterface.TAG_DATETIME_ORIGINAL));
Log.d("TAG_DATETIME_DIGITIZED", exifInterface.getAttribute(ExifInterface.TAG_DATETIME_DIGITIZED));
Log.d("TAG_SUBSEC_TIME", exifInterface.getAttribute(ExifInterface.TAG_SUBSEC_TIME));
Log.d("TAG_SUBSEC_TIME_ORIGINAL", exifInterface.getAttribute(ExifInterface.TAG_SUBSEC_TIME_ORIGINAL));
Log.d("TAG_SUBSEC_TIME_DIGITIZED", exifInterface.getAttribute(ExifInterface.TAG_SUBSEC_TIME_DIGITIZED));
D/TAG_DATETIME: 2019:01:13 08:23:01
D/TAG_DATETIME_ORIGINAL: 2019:01:13 08:23:01
D/TAG_DATETIME_DIGITIZED: 2019:01:13 08:23:01
D/TAG_SUBSEC_TIME: 038
D/TAG_SUBSEC_TIME_ORIGINAL: 038
D/TAG_SUBSEC_TIME_DIGITIZED: 038

この6種類のタグですが、ログで見ると出力される内容が2パターンしかないので使い分けが分かりづらいですが、それぞれ、こんな意味を持ちます。

  • TAG_DATETIME(DateTime)
    ファイルの変更日時
  • TAG_DATETIME_ORIGINAL(DateTimeDigitized)
    原画像データの作成日時
  • TAG_DATETIME_DIGITIZED(DateTimeOriginal)
    デジタルデータの生成日時
  • TAG_SUBSEC_TIME(SubsecTime)
    ファイルの変更日時の小数点以下の秒単位
  • TAG_SUBSEC_TIME_ORIGINAL(DateTimeDigitized)
    原画像データの作成日時の小数点以下の秒単位
  • TAG_SUBSEC_TIME_DIGITIZED(SubsecTimeOriginal)
    デジタルデータの作成日時の小数点以下の秒単位

スマホやデジカメで撮影した写真の場合、ファイルの変更日時はともかく、原画像データの生成日時とデジタルデータの作成日時は、殆どの場合において同じ値になります。
(もしかしたら、撮影の瞬間にCCDが受けたデータ(原画像データの生成)からスマホやデジカメが映像処理して作成するデータ(デジタルデータの作成)までに時間が掛かったとしたら変わってくるかも知れません?)

タグの仕様について

これらの6種類のタグの仕様について、もう少し詳しく見ていきましょう。

ファイル変更日時 DateTime

画像の作成された日付と時間で、ファイル変更日時として用いる。
フォーマットは「YYYY:MM:DD HH:MM:SS」で、0~24時表記、日付と時間の間に空白文字を1つ埋める。
日時不明の場合は、コロン以外を空白文字で埋めるか、すべてを空白文字で埋める。

原画像データの生成日時 DateTimeOriginal

原画像データの生成された日付と時間で、撮影された日付と時間を記載する。
フォーマットは「YYYY:MM:DD HH:MM:SS」で、0~24時表記、日付と時間の間に空白文字を1つ埋める。
日時不明の場合は、コロン以外を空白文字で埋めるか、すべてを空白文字で埋める。

デジタルデータ作成日時 DateTimeDigitized

画像がデジタルデータ化された日付と時間で撮影と同時にファイル化された場合、DateTimeOriginalとDateTimeDigitizedは同じ値になる。
フォーマットは「YYYY:MM:DD HH:MM:SS」で、0~24時表記、日付と時間の間に空白文字を1つ埋める。
日時不明の場合は、コロン以外を空白文字で埋めるか、すべてを空白文字で埋める。

ファイルの変更日時の小数点以下の秒単位 SubsecTime

DateTimeタグに関連して時刻を小数点以下の秒単位まで記録する。
桁数については仕様書には記載されていませんでした。

原画像データの作成日時の小数点以下の秒単位 SubsecTimeOriginal

DateTimeOriginalタグに関連して時刻を小数点以下の秒単位まで記録する。
桁数については仕様書には記載されていませんでした。

デジタルデータの作成日時の小数点以下の秒単位 SubsecTimeDigitized

DateTimeDigitizedタグに関連して時刻を小数点以下の秒単位まで記録する。
桁数については仕様書には記載されていませんでした。

記録するデータの例

例えば、1998年9月1日9時15分30.130秒の場合は、以下のようになります。
DateTime 1998:09:01 09:15:30
SubSecTime 130

Exifの仕様について

このExifの仕様ですが、MicrosoftやApple、Intel、Googleなどが主体となっているのだろうと思っていたら、なんと、カメラ映像機器工業会というところで行っているそうです。
そして、そもそも、Exifを開発したのは富士フイルムだというから驚きです。

この「YYYY:MM:DD HH:MM:SS」がいかにも日本風だったので、海外のデータを扱う場合にはフォーマット変換しなくてはいけないと思いましたが、その必要はなさそうです。

CIPA 一般社団法人カメラ映像機器工業会: CIPA規格類
Exchangeable image file format - Wikipedia

Exif Ver.2.31

ここまで6種類のタグを見てきましたが、Ver.2.31から以下が追加されていることが分かりました。

DateTimeの時差データ OffsetTime
DateTimeOriginalの時差データ OffsetTimeOriginal
DateTimeDigitizedの時差データ OffsetTimeDigitized

時差ということで、UTC(協定世界時)を基準とした時差(サマータイムを含む)を記録するためのタグです。
フォーマットは「±HH:MM」で「±」の部分は「+」または「-」になります。

http://www.cipa.jp/std/documents/j/DC-008-2016-J.pdf

この時差のタグは、現バージョンのAndroid(ExifInterface)では取り扱うことはできませんでした。
そのうちにExifInterface.TAG_SUBSEC_OFFSET_TIME、ExifInterface.TAG_SUBSEC_OFFSET_TIME_DIGITIZED、ExifInterface.TAG_SUBSEC_OFFSET_TIME_ORIGINALというのが追加されると思います。

以上、スマホやデジカメで撮影した写真に埋め込まれるExifについてでした。