X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fjpeg%2FExternalExifLibrary.java;h=4d06a2728ccfb42d41a83a2486bb98b35b5546ee;hb=81843c3d8d0771bf00d0f26034a13aa515465c78;hp=1c64b4e247fcd83ba4632050667a61fe09c1c5c3;hpb=140e9d165f85c3d4f0435a311e091209313faa2a;p=GpsPrune.git diff --git a/tim/prune/jpeg/ExternalExifLibrary.java b/tim/prune/jpeg/ExternalExifLibrary.java index 1c64b4e..4d06a27 100644 --- a/tim/prune/jpeg/ExternalExifLibrary.java +++ b/tim/prune/jpeg/ExternalExifLibrary.java @@ -2,17 +2,20 @@ package tim.prune.jpeg; import java.io.File; +import com.drew.imaging.ImageMetadataReader; import com.drew.lang.Rational; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; -import com.drew.metadata.exif.ExifDirectory; +import com.drew.metadata.exif.ExifSubIFDDirectory; +import com.drew.metadata.exif.ExifIFD0Directory; import com.drew.metadata.exif.ExifReader; +import com.drew.metadata.exif.ExifThumbnailDirectory; import com.drew.metadata.exif.GpsDirectory; /** * Class to act as a gateway into the external exif library functions. * This should be the only class with dependence on the lib-metadata-extractor-java - * classes (which are NOT delivered with Prune). + * classes (which are NOT delivered with GpsPrune). * This class will not compile without this extra dependency (but is not required if * the ExifGateway uses the InternalExifLibrary instead). * Should not be included if the internal library will be used (from jpeg.drew package). @@ -30,73 +33,92 @@ public class ExternalExifLibrary implements ExifLibrary // Read exif data from picture try { - Metadata metadata = new Metadata(); - new ExifReader(inFile).extract(metadata); + Metadata metadata = ImageMetadataReader.readMetadata(inFile); if (metadata.containsDirectory(GpsDirectory.class)) { Directory gpsdir = metadata.getDirectory(GpsDirectory.class); - if (gpsdir.containsTag(GpsDirectory.TAG_GPS_LATITUDE) - && gpsdir.containsTag(GpsDirectory.TAG_GPS_LONGITUDE) - && gpsdir.containsTag(GpsDirectory.TAG_GPS_LATITUDE_REF) - && gpsdir.containsTag(GpsDirectory.TAG_GPS_LONGITUDE_REF)) + if (gpsdir.containsTag(GpsDirectory.TAG_LATITUDE) + && gpsdir.containsTag(GpsDirectory.TAG_LONGITUDE) + && gpsdir.containsTag(GpsDirectory.TAG_LATITUDE_REF) + && gpsdir.containsTag(GpsDirectory.TAG_LONGITUDE_REF)) { - data.setLatitudeRef(gpsdir.getString(GpsDirectory.TAG_GPS_LATITUDE_REF)); - Rational[] latRats = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE); + data.setLatitudeRef(gpsdir.getString(GpsDirectory.TAG_LATITUDE_REF)); + Rational[] latRats = gpsdir.getRationalArray(GpsDirectory.TAG_LATITUDE); + double seconds = ExifGateway.convertToPositiveValue(latRats[2].getNumerator(), latRats[2].getDenominator()); data.setLatitude(new double[] {latRats[0].doubleValue(), - latRats[1].doubleValue(), latRats[2].doubleValue()}); - data.setLongitudeRef(gpsdir.getString(GpsDirectory.TAG_GPS_LONGITUDE_REF)); - Rational[] lonRats = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE); + latRats[1].doubleValue(), seconds}); + data.setLongitudeRef(gpsdir.getString(GpsDirectory.TAG_LONGITUDE_REF)); + Rational[] lonRats = gpsdir.getRationalArray(GpsDirectory.TAG_LONGITUDE); + seconds = ExifGateway.convertToPositiveValue(lonRats[2].getNumerator(), lonRats[2].getDenominator()); data.setLongitude(new double[] {lonRats[0].doubleValue(), - lonRats[1].doubleValue(), lonRats[2].doubleValue()}); + lonRats[1].doubleValue(), seconds}); } // Altitude (if present) - if (gpsdir.containsTag(GpsDirectory.TAG_GPS_ALTITUDE) && gpsdir.containsTag(GpsDirectory.TAG_GPS_ALTITUDE_REF)) + if (gpsdir.containsTag(GpsDirectory.TAG_ALTITUDE) && gpsdir.containsTag(GpsDirectory.TAG_ALTITUDE_REF)) { - data.setAltitude(gpsdir.getRational(GpsDirectory.TAG_GPS_ALTITUDE).intValue()); - byte altRef = (byte) gpsdir.getInt(GpsDirectory.TAG_GPS_ALTITUDE_REF); + data.setAltitude(gpsdir.getRational(GpsDirectory.TAG_ALTITUDE).intValue()); + byte altRef = (byte) gpsdir.getInt(GpsDirectory.TAG_ALTITUDE_REF); data.setAltitudeRef(altRef); } // Timestamp and datestamp (if present) - final int TAG_GPS_DATESTAMP = 0x001d; - if (gpsdir.containsTag(GpsDirectory.TAG_GPS_TIME_STAMP) && gpsdir.containsTag(TAG_GPS_DATESTAMP)) + final int TAG_DATESTAMP = 0x001d; + if (gpsdir.containsTag(GpsDirectory.TAG_TIME_STAMP) && gpsdir.containsTag(TAG_DATESTAMP)) { - Rational[] times = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_TIME_STAMP); + Rational[] times = gpsdir.getRationalArray(GpsDirectory.TAG_TIME_STAMP); data.setGpsTimestamp(new int[] {times[0].intValue(), times[1].intValue(), times[2].intValue()}); - Rational[] dates = gpsdir.getRationalArray(TAG_GPS_DATESTAMP); + Rational[] dates = gpsdir.getRationalArray(TAG_DATESTAMP); if (dates != null) { data.setGpsDatestamp(new int[] {dates[0].intValue(), dates[1].intValue(), dates[2].intValue()}); } } + + // Image bearing (if present) + if (gpsdir.containsTag(GpsDirectory.TAG_IMG_DIRECTION) && gpsdir.containsTag(GpsDirectory.TAG_IMG_DIRECTION_REF)) + { + Rational bearing = gpsdir.getRational(GpsDirectory.TAG_IMG_DIRECTION); + if (bearing != null) { + data.setBearing(bearing.doubleValue()); + } + } } // Tags from Exif directory - if (metadata.containsDirectory(ExifDirectory.class)) + if (metadata.containsDirectory(ExifSubIFDDirectory.class)) { - Directory exifdir = metadata.getDirectory(ExifDirectory.class); + Directory exifdir = metadata.getDirectory(ExifSubIFDDirectory.class); // Take time and date from exif tags - if (exifdir.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) { - data.setOriginalTimestamp(exifdir.getString(ExifDirectory.TAG_DATETIME_ORIGINAL)); + if (exifdir.containsTag(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL)) { + data.setOriginalTimestamp(exifdir.getString(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL)); } // Also take "digitized" timestamp - if (exifdir.containsTag(ExifDirectory.TAG_DATETIME_DIGITIZED)) { - data.setDigitizedTimestamp(exifdir.getString(ExifDirectory.TAG_DATETIME_DIGITIZED)); + if (exifdir.containsTag(ExifSubIFDDirectory.TAG_DATETIME_DIGITIZED)) { + data.setDigitizedTimestamp(exifdir.getString(ExifSubIFDDirectory.TAG_DATETIME_DIGITIZED)); } + } + if (metadata.containsDirectory(ExifIFD0Directory.class)) + { + Directory exifdir = metadata.getDirectory(ExifIFD0Directory.class); // Photo rotation code - if (exifdir.containsTag(ExifDirectory.TAG_ORIENTATION)) { - data.setOrientationCode(exifdir.getInt(ExifDirectory.TAG_ORIENTATION)); + if (exifdir.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { + data.setOrientationCode(exifdir.getInt(ExifIFD0Directory.TAG_ORIENTATION)); // NOTE: this presumably takes the _last_ orientation value found, not the first. } + } - // Thumbnail - if (exifdir.containsTag(ExifDirectory.TAG_THUMBNAIL_DATA)) + if (metadata.containsDirectory(ExifThumbnailDirectory.class)) + { + ExifThumbnailDirectory exifdir = metadata.getDirectory(ExifThumbnailDirectory.class); + + // TODO: Check this thumbnail stuff + if (exifdir.hasThumbnailData()) { - // Make a copy of the byte data rather than keeping a reference to extracted array - byte[] tdata = exifdir.getByteArray(ExifDirectory.TAG_THUMBNAIL_DATA); + // Make a copy of the byte data + byte[] tdata = exifdir.getThumbnailData(); byte[] thumb = new byte[tdata.length]; System.arraycopy(tdata, 0, thumb, 0, tdata.length); data.setThumbnailImage(thumb); @@ -106,10 +128,12 @@ public class ExternalExifLibrary implements ExifLibrary } catch (Exception e) { // Exception reading metadata, just ignore it + //System.err.println("Error: " + e.getClass().getName() + " - " + e.getMessage()); } return data; } + /** * Check whether the exifreader class can be correctly resolved * @return true if it looks ok