Introduction
In the previous post, I showed available tags in ExifTagConstants, TiffTagConstants, GpsTagConstants classes.
In this post, I will show you code snippet for extracting metada from jpeg using the tags.
In order to run example code, you should download commons-imaging.jar from here. Somehow the official homepage of Commons Imaging doesn't provide commons-imaging.jar!!
Code
package com.dulesoftware.image;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.Imaging;
import org.apache.commons.imaging.common.IImageMetadata;
import org.apache.commons.imaging.common.IImageMetadata.IImageMetadataItem;
import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
import org.apache.commons.imaging.formats.tiff.TiffField;
import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfo;
import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants;
public class PrintExifMetadata {
public static void main(String[] args) throws Exception {
printMetaData(new File("c:/temp/metadata_eample.jpg"));
}
public static void printMetaData(final File file) throws ImageReadException,
IOException,
IllegalArgumentException,
IllegalAccessException {
// get all metadata stored in EXIF format (ie. from JPEG or TIFF).
IImageMetadata metadata = Imaging.getMetadata(file);
if (!(metadata instanceof JpegImageMetadata)) {
throw new RuntimeException("Only support " + JpegImageMetadata.class.getSimpleName());
}
JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
// JPEG EXIF metadata
List<Field> exifTagfields = getTagInfoDefinedInClass(ExifTagConstants.class);
System.out.println("=== " + ExifTagConstants.class.getSimpleName() + " ===");
printTagInfos(exifTagfields, jpegMetadata);
// Tiff metadata
List<Field> tiffTagfields = getTagInfoDefinedInClass(TiffTagConstants.class);
System.out.println("=== " + TiffTagConstants.class.getSimpleName() + " ===");
printTagInfos(tiffTagfields, jpegMetadata);
// Gps metadata
List<Field> gpsTagfields = getTagInfoDefinedInClass(GpsTagConstants.class);
System.out.println("=== " + GpsTagConstants.class.getSimpleName() + " ===");
printTagInfos(gpsTagfields, jpegMetadata);
// simple interface to EXIF jpegMetadata
TiffImageMetadata exifMetadata = jpegMetadata.getExif();
if (null != exifMetadata) {
System.out.println("=== ExifMetadata ===");
jpegMetadata.getExif().getAllFields().stream().forEach(System.out::println);
System.out.println();
}
// All IImageMetadataItem
List<IImageMetadataItem> items = jpegMetadata.getItems();
printIImageMetadataItems(items);
}
private static void printTagInfos(List<Field> tagfields, JpegImageMetadata jpegMetadata)
throws IllegalAccessException, IllegalArgumentException, ImageReadException {
for (Field field : tagfields) {
printTagValue(jpegMetadata, (TagInfo) field.get(null));
}
System.out.println();
}
private static void printIImageMetadataItems(List<IImageMetadataItem> items) {
System.out.println("=== " + IImageMetadataItem.class.getSimpleName() + " in " + JpegImageMetadata.class.getSimpleName() + " ===");
for (IImageMetadataItem item : items) {
System.out.println(item);
}
System.out.println();
}
private static void printTagValue(JpegImageMetadata jpegMetadata, TagInfo tagInfo)
throws ImageReadException {
try {
// ---------------------------------
// KEY PART: Extract EXIF by TagInfo
// if you use findEXIFValueWithExactMatch,
// the method throws NullPointerException when the provided tag does not present in the metadata
// ---------------------------------
TiffField field = jpegMetadata.findEXIFValue(tagInfo);
if (field != null) {
// get actual stored value in metadata
Object value = field.getValue();
System.out.println(tagInfo.name + ": " + toString(value));
}
} catch (NullPointerException e) {
}
}
private static List<Field> getTagInfoDefinedInClass(Class<?> clazz) {
Field[] declaredFields = clazz.getDeclaredFields();
return Arrays.stream(declaredFields)
.filter(field
-> TagInfo.class.isAssignableFrom(field.getType())
&& Modifier.isStatic(field.getModifiers())
)
.collect(Collectors.toList());
}
public static String toString(Object value) {
if (value instanceof int[]) {
return Arrays.toString((int[]) value);
} else if (value instanceof boolean[]) {
return Arrays.toString((boolean[]) value);
} else if (value instanceof byte[]) {
return Arrays.toString((byte[]) value);
} else if (value instanceof char[]) {
return Arrays.toString((char[]) value);
} else if (value instanceof long[]) {
return Arrays.toString((long[]) value);
} else if (value instanceof short[]) {
return Arrays.toString((short[]) value);
} else if (value instanceof double[]) {
return Arrays.toString((double[]) value);
} else if (value instanceof float[]) {
return Arrays.toString((float[]) value);
} else if (value.getClass().isArray()) {
return Arrays.toString((Object[]) value);
} else {
return value.toString();
}
}
}
Example Result
I will show you the example execution result of the above code.The test image is below.
The code outputs following result from the test image.
=== ExifTagConstants === Software: Picasa JpgFromRawStart: 4488 OtherImageStart: 4488 JpgFromRawLength: 6780 OtherImageLength: 6780 ExifOffset: 2172 ExifVersion: [48, 50, 50, 48] ExifImageWidth: 1440 ExifImageLength: 1440 ImageUniqueID: 199e785efd74401dff564baa559c2f25 === TiffTagConstants === Compression: 6 ImageDescription: MetaData Example XResolution: 72 YResolution: 72 ResolutionUnit: 2 Software: Picasa === GpsTagConstants === === ExifMetadata === 270 (0x10e: ImageDescription): 'MetaData Example' (17 ASCII) 305 (0x131: Software): 'Picasa' (7 ASCII) 34665 (0x8769: ExifOffset): 2172 (1 Long) 40091 (0x9c9b: XPTitle): 'MetaData Example' (34 Byte) 40092 (0x9c9c: XPComment): 'Test Comments' (28 Byte) 59932 (0xea1c: Padding): 28, -22, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... (2060) (2060 Undefined) 36864 (0x9000: ExifVersion): 48, 50, 50, 48 (4 Undefined) 40962 (0xa002: ExifImageWidth): 1440 (1 Long) 40963 (0xa003: ExifImageLength): 1440 (1 Long) 42016 (0xa420: ImageUniqueID): '199e785efd74401dff564baa559c2f25' (33 ASCII) 59932 (0xea1c: Padding): 28, -22, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... (2060) (2060 Undefined) 259 (0x103: Compression): 6 (1 Short) 282 (0x11a: XResolution): 72 (1 Rational) 283 (0x11b: YResolution): 72 (1 Rational) 296 (0x128: ResolutionUnit): 2 (1 Short) 513 (0x201: JpgFromRawStart): 4488 (1 Long) 514 (0x202: JpgFromRawLength): 6780 (1 Long) === IImageMetadataItem in JpegImageMetadata === ImageDescription: 'MetaData Example' Software: 'Picasa' ExifOffset: 2172 XPTitle: 'MetaData Example' XPComment: 'Test Comments' Padding: 28, -22, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... (2060) ExifVersion: 48, 50, 50, 48 ExifImageWidth: 1440 ExifImageLength: 1440 ImageUniqueID: '199e785efd74401dff564baa559c2f25' Padding: 28, -22, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0... (2060) Compression: 6 XResolution: 72 YResolution: 72 ResolutionUnit: 2 JpgFromRawStart: 4488 JpgFromRawLength: 6780 Caption/Abstract: MetaData Example

コメント