jiichan.com

PROGRAMMING

Exif情報を簡単に取得できるライブラリ

孫の写真を撮影年月別に整理するため、ワンクリックで振り分けできるツールを以前作りました。
ファイルのプロパティの更新年月日を見て振り分けるものでしたが、撮影年月日とは違うため、なかには手作業で再度振り分ける場合もありました。
Exif情報を取得できれば撮影年月日で振り分けできると思いネットを探したら、metadata-extractorというライブラリの存在を知り早速試してみました。


-----2016.11.17(追加)-----
「個別タグの取得方法」があった方が良いので追加しました。

ライブラリの準備

ライブラリは現在の最新バージョンである metadata-extractor-2.8.1 をダウンロードしました。
このページにサンプルも掲載されているのでコピペで簡単にできました。

metadata-extractorのサイト:https://drewnoakes.com/code/exif/
ダウンロードのページ:https://github.com/drewnoakes/metadata-extractor/releases
ダウンロードしたmetadata-extractor-2.8.1.zipを解凍すると

   ・ metadata-extractor-2.8.1.jar
   ・ xmpcore-5.1.2.jar

の2個のjarがあり、それを使うことになります。

Exif情報取得のコード

インポートは次の4個になります。


import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
 

メインのExif情報取得のコードです。


File jpegFile = new File("c:\\DSC00001.jpg");
Metadata metadata = ImageMetadataReader.readMetadata(jpegFile);
for (Directory directory : metadata.getDirectories()) {
	for (Tag tag : directory.getTags()) {
		System.out.format("[%s] %s = %s",
			tag.getDirectoryName(), tag.getTagName(), tag.getDescription());
		System.out.println();
	}
}

jpegファイルのみを対象にする場合はコードの2行目を
Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
に変更するといいようです。処理が速くなるようですが自分ではちょっと分かりませんでした。

このコードを実行して出力された全Exif情報が次のリストです。
最初のカッコで囲まれた部分がDirectoryName、次がTagName、イコールの後がDescriptionです。


[Exif IFD0] Image Description =                                
[Exif IFD0] Make = SONY
[Exif IFD0] Model = HDR-CX430V
[Exif IFD0] Orientation = Top, left side (Horizontal / normal)
[Exif IFD0] X Resolution = 350 dots per inch
[Exif IFD0] Y Resolution = 350 dots per inch
[Exif IFD0] Resolution Unit = Inch
[Exif IFD0] Software = HDR-CX430V v1.00
[Exif IFD0] Date/Time = 2014:12:31 16:21:48
[Exif IFD0] YCbCr Positioning = Datum point
[Exif IFD0] Print IM = [28 bytes]
[Exif SubIFD] Exposure Time = 1/60 sec
[Exif SubIFD] F-Number = f/2.0
[Exif SubIFD] Exposure Program = Program normal
[Exif SubIFD] Exif Version = 2.30
[Exif SubIFD] Date/Time Original = 2014:12:31 16:21:48
[Exif SubIFD] Date/Time Digitized = 2014:12:31 16:21:48
[Exif SubIFD] Components Configuration = YCbCr
[Exif SubIFD] Compressed Bits Per Pixel = 2 bits/pixel
[Exif SubIFD] Exposure Bias Value = 0 EV
[Exif SubIFD] Max Aperture Value = f/2.0
[Exif SubIFD] Metering Mode = Multi-segment
[Exif SubIFD] White Balance = Unknown
[Exif SubIFD] Flash = Flash did not fire, auto
[Exif SubIFD] Focal Length = 2.2 mm
[Exif SubIFD] User Comment = 
[Exif SubIFD] FlashPix Version = 1.00
[Exif SubIFD] Color Space = sRGB
[Exif SubIFD] Exif Image Width = 3984 pixels
[Exif SubIFD] Exif Image Height = 2240 pixels
[Exif SubIFD] File Source = Digital Still Camera (DSC)
[Exif SubIFD] Scene Type = Directly photographed image
[Exif SubIFD] Custom Rendered = Normal process
[Exif SubIFD] Exposure Mode = Auto exposure
[Exif SubIFD] White Balance Mode = Auto white balance
[Exif SubIFD] Digital Zoom Ratio = 1
[Exif SubIFD] Scene Capture Type = Standard
[Exif SubIFD] Contrast = None
[Exif SubIFD] Saturation = None
[Exif SubIFD] Sharpness = None
[Exif SubIFD] Lens Specification = 19/10 570/10 18/10 40/10
[JPEG] Compression Type = Baseline
[JPEG] Data Precision = 8 bits
[JPEG] Image Height = 2240 pixels
[JPEG] Image Width = 3984 pixels
[JPEG] Number of Components = 3
[JPEG] Component 1 =
	Y component: Quantization table 0, Sampling factors 1 horiz/2 vert
[JPEG] Component 2 =
	Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert
[JPEG] Component 3 =
	Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert
[File] File Name = DSC00001.jpg
[File] File Size = 2823264 bytes
[File] File Modified Date = Wed Dec 31 16:21:54 JST 2014
[Exif Thumbnail] Thumbnail Compression = JPEG (old-style)
[Exif Thumbnail] Image Description =                                
[Exif Thumbnail] Make = SONY
[Exif Thumbnail] Model = HDR-CX430V
[Exif Thumbnail] Orientation = Top, left side (Horizontal / normal)
[Exif Thumbnail] X Resolution = 72 dots per inch
[Exif Thumbnail] Y Resolution = 72 dots per inch
[Exif Thumbnail] Resolution Unit = Inch
[Exif Thumbnail] Software = HDR-CX430V v1.00
[Exif Thumbnail] Date/Time = 2014:12:31 16:21:48
[Exif Thumbnail] Thumbnail Offset = 39010 bytes
[Exif Thumbnail] Thumbnail Length = 10664 bytes
[Exif Thumbnail] YCbCr Positioning = Datum point
[GPS] GPS Version ID = 2.300
[GPS] GPS Status = Void (Measurement Interoperability)
[GPS] GPS Map Datum = WGS-84
[GPS] GPS Differential = No Correction
[Interoperability] Interoperability Index =
	Recommended Exif Interoperability Rules (ExifR98)
[Interoperability] Interoperability Version = 1.00
[Sony Makernote] Panorama =
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[Sony Makernote] Unknown tag (0x2000) = 0
[Sony Makernote] Rating = 0
[Sony Makernote] Unknown tag (0x2003) = 
[Sony Makernote] Contrast = 0
[Sony Makernote] Brightness = 0
[Sony Makernote] Long Exposure Noise Reduction = 0
[Sony Makernote] HDR = 0
[Sony Makernote] Unknown tag (0x200c) = 0 0 0
[Sony Makernote] Unknown tag (0x200d) = 1
[Sony Makernote] Shot Info = [390 bytes]
[Sony Makernote] Color Mode Setting = Standard
[Sony Makernote] Scene Mode = Auto
[Sony Makernote] Zone Matching = ISO Setting Used
[Sony Makernote] Dynamic Range Optimizer = Off
[Sony Makernote] Image Stabilisation = On
[Sony Makernote] Preview Image Size = 1080 1920
[Sony Makernote] Flash Exposure Compensation = 0 EV
[Sony Makernote] Multi Frame Noise Reduction = 0
[Sony Makernote] Picture Effect = Off
[Sony Makernote] Soft Skin Effect = Off
[Sony Makernote] Unknown tag (0x2017) = 0
[Sony Makernote] Unknown tag (0x2018) = 0
[Sony Makernote] Unknown tag (0x2019) = 0
[Sony Makernote] Unknown tag (0x201a) = 0
[Sony Makernote] Focus Mode = Manual
[Sony Makernote] Unknown tag (0x201c) = 0
[Sony Makernote] Unknown tag (0x201d) = 0 0
[Sony Makernote] AF Point Selected = Auto
[Sony Makernote] Unknown tag (0x201f) = 0 0 0 0
[Sony Makernote] Unknown tag (0x2020) = 36 0 0 66 1 2 132 128 64 194
[Sony Makernote] Unknown tag (0x2021) = 0
[Sony Makernote] Unknown tag (0x2022) = 128 10 133 2 50 107 0 28 192 2 40 0 0
[Sony Makernote] Unknown tag (0x2023) = 0
[Sony Makernote] Macro = Off
[Sony Makernote] Exposure Mode = Auto
[Sony Makernote] Focus Mode = 0
[Sony Makernote] AF Mode = Default
[Sony Makernote] AF Illuminator = Off
[Sony Makernote] Unknown tag (0xb045) = 0
[Sony Makernote] Unknown tag (0xb046) = 0
[Sony Makernote] Quality = Normal
[Sony Makernote] Flash Level = Normal
[Sony Makernote] Release Mode = Normal
[Sony Makernote] Sequence Number = Single
[Sony Makernote] Anti Blur = On (Continuous)
[Sony Makernote] Unknown tag (0xb04c) = 1
[Sony Makernote] Unknown tag (0xb04d) = 0
[Sony Makernote] Long Exposure Noise Reduction = On
[Sony Makernote] Dynamic Range Optimizer = 0
[Sony Makernote] High ISO Noise Reduction = 0
[Sony Makernote] Unknown tag (0xb051) = 0
[Sony Makernote] Intelligent Auto = 1
[Sony Makernote] Unknown tag (0xb053) = 0
[Sony Makernote] White Balance 2 = 0
[Sony Makernote] Unknown tag (0x9400) = [156 bytes]
[Sony Makernote] Unknown tag (0x9401) = [4096 bytes]
[Sony Makernote] Unknown tag (0x9402) = [400 bytes]
[Sony Makernote] Unknown tag (0x9403) = [400 bytes]
[Sony Makernote] Unknown tag (0x9404) = [556 bytes]
[Sony Makernote] Unknown tag (0x9405) = [1836 bytes]
[Sony Makernote] Unknown tag (0x9407) = [64 bytes]
[Sony Makernote] Unknown tag (0x9408) = [1000 bytes]
[Sony Makernote] Unknown tag (0x9409) = [1344 bytes]
[Sony Makernote] Unknown tag (0x940a) = [272 bytes]
[Sony Makernote] Unknown tag (0x940b) = [400 bytes]
[Sony Makernote] Unknown tag (0x940c) = [64 bytes]
[Sony Makernote] Unknown tag (0x940d) = [1260 bytes]
[Sony Makernote] Unknown tag (0x940e) = [12288 bytes]
[Sony Makernote] Unknown tag (0xa100) = [64 bytes]
[Sony Makernote] Unknown tag (0x2010) = [6512 bytes]
[Sony Makernote] Unknown tag (0x9410) = [5376 bytes]

Exif情報の絞り込み

自分は撮影年月日が必要でしたので4行目のforループ内を次のように変更して使いました。


if(tag.getTagName().startsWith("Date/Time")){
	System.out.println(tag.getTagName() + " = " + tag.getDescription());
}

getTagName()の先頭に Date/Time の文字を含むデータを抽出すると次のような出力になりました。


Date/Time - 2014:12:31 16:21:48
Date/Time - 2014:12:31 16:21:48
Date/Time Original - 2014:12:31 16:21:48
Date/Time Digitized - 2014:12:31 16:21:48

「Date/Time Original」 が撮影年月日なので文字を 「Date/Time Original」に絞り込んでデータを抽出すると目的が達成できることになります。

便利です。

個別タグの取得方法

取得したいタグが決まっている場合はそのタグが含まれるディレクトリを指定して取得した方が良いと思います。
下記のコードはオリエンテーションタグの例です。


// Exif情報を取得
Metadata metadata = ImageMetadataReader.readMetadata(f);
// 個別タグ取得
ExifIFD0Directory directory =
	metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);

// TAG_ORIENTATIONを含んだディレクトリの存在確認
if(directory != null){
	orientation =
		directory.getInteger(ExifIFD0Directory.TAG_ORIENTATION);
}else{
	orientation = 1;
}

カメラの機種によってはカメラの傾きを感知して撮影するものもあり、 その場合はオリエンテーションタグを含んだディレクトリが無いことがあります。
そのため、NullPointerException回避のためのコードもあったほうが良いようです。

主なタグのいろいろです。
・カメラメーカー:ExifIFDDirectory.TAG_MAKE
・カメラモデル:ExifIFDDirectory.TAG_MODEL
・絞り値:ExifSubIFDDirectory.TAG_FNUMBER
・露出時間:ExifSubIFDDirectory.TAG_EXPOSURE_TIME
・ISO感度:ExifSubIFDDirectory.TAG_ISO_EQUIVALENT
・露出:ExifSubIFDDirectory.TAG_EXPOSURE_BIAS
・焦点距離:ExifSubIFDDirectory.TAG_FOCAL_LENGTH
・撮影日時:ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL
・回転情報:ExifIFD0Directory.TAG_ORIENTATION