手作りソフト実験室
手作りソフト実験室では、基本的なプログラミングで何が出来るかを実験します。
1 指定フォルダ以下のJPGファイルEXIF情報をCSV出力する
開発環境がフリーで用意できるjavaにて実験です。 最初にする実験にしては、初心者向きでないかもしれません。
手元のPCでは2万枚以上の画像ファイルを検索し、内部記録情報をファイルにリスト出力できました。ただし実験ソフトなのでGUI処理は含みません。
指定フォルダ以下のファイル再帰検索
C言語で同じ処理を書くと大変ですが、javaには指定フォルダ(ディレクトリ)のファイルを列挙する便利な機能があります。4行目の dir.listFiles() です。
//指定する親ディレクトリと出力ファイルのハンドラをパラメータとして渡す
private static void WriteExifList(File dir, PrintWriter pw) {
File[] fs = dir.listFiles();
for (File f : fs) {
//ディレクトリか判断
if (f.isDirectory()) {
//ディレクトリならば再帰処理(自分自身を呼ぶ
WriteExifList(f, pw);
} else if (f.isFile()) {
try {
if(isJpgFile(f)){
f.getCanonicalPath();
try {
//Exif情報抽出
//出力処理
//
//以下、例外処理
} catch (JpegProcessingException e) {
// handle exception
} catch (IOException e) {
// handle exception
} catch (NullPointerException e) {
// handle exception
}
}
//例外処理
} catch (IOException ex) {
// do nothing
}
}
}
}
JPEGファイルよりEXIF情報(撮影時のデータ)を抽出
公開されているEXIF抽出JAVAライブラリmetadata-extractorを利用させていただきました。 releases pageにあるmetadata-extractor-2.9.1.zipをダウンロードして解凍します。
解凍した ①metadata-extractor-2.9.1.jarと②xmpcore-5.1.2.jarをJava開発環境とランタイムライブラリ2か所に保存します。 使用方法についてはここのExample 2を参考にしました。
//必要なライブラリをインポート
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.imaging.jpeg.JpegSegmentMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifReader;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.iptc.IptcReader;
// 画像ファイルのハンドラを f とすると以下のように撮影日時情報を取り出します
Metadata metadata = JpegMetadataReader.readMetadata(f, readers);
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_DIGITIZED);
ソースコード全体
画像ファイルは拡張子が"jpg"か"JPG"かで判断する簡易方法です。EXIF情報の中から今回は記録日時情報だけ取り出しています。
なお、末尾一行は不要です。
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.imaging.jpeg.JpegSegmentMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifReader;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.iptc.IptcReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
public class RecDir {
// pwd: the current directory
static String pwd = new File(".").getAbsoluteFile().getParent();
static int n=1;
public static void main(String[] args) {
File dir = new File("j:\\マイピクチャ\\2015");
//File dir = new File("j:\\マイピクチャ");
//File dir = new File(pwd);
try {
//BufferedWriter bw=new BufferedWriter(new FileWriter("jpgList.txt"));
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("jpgList.csv")));
WriteExifList(dir, pw);
pw.close();
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
}
private static void WriteExifList(File dir, PrintWriter pw) {
File[] fs = dir.listFiles();
for (File f : fs) {
if (f.isDirectory()) {
WriteExifList(f, pw);
} else if (f.isFile()) {
try {
if(isJpgFile(f)){
String path = f.getCanonicalPath();
try {
Iterable readers = Arrays.asList(new ExifReader(), new IptcReader());
Metadata metadata = JpegMetadataReader.readMetadata(f, readers);
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_DIGITIZED);
System.out.print(n+" ");
System.out.print(date+" ");
System.out.println(f.getCanonicalPath());
pw.print(n);
pw.print("\t");
pw.write(date.toString());
pw.write("\t");
pw.write(path);
pw.write("\n");
n++;
//print(metadata);
} catch (JpegProcessingException e) {
// handle exception
} catch (IOException e) {
// handle exception
} catch (NullPointerException e) {
// handle exception
}
}
} catch (IOException ex) {
// do nothing
}
}
}
}
static boolean isJpgFile(File file) {
return file.isFile() && file.canRead() && ((file.getPath().endsWith(".jpg") || (file.getPath().endsWith(".JPG"))));
}
}
