1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
package tim.prune.jpeg;
import java.io.File;
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.ExifReader;
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).
* 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).
*/
public class ExternalExifLibrary implements ExifLibrary
{
/**
* Use the _external_ exif library to get the data from the given file
* @param inFile file to access
* @return Jpeg data if available, otherwise null
*/
public JpegData getJpegData(File inFile)
{
JpegData data = new JpegData();
// Read exif data from picture
try
{
Metadata metadata = new Metadata();
new ExifReader(inFile).extract(metadata);
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))
{
data.setLatitudeRef(gpsdir.getString(GpsDirectory.TAG_GPS_LATITUDE_REF));
Rational[] latRats = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE);
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);
data.setLongitude(new double[] {lonRats[0].doubleValue(),
lonRats[1].doubleValue(), lonRats[2].doubleValue()});
}
// Altitude (if present)
if (gpsdir.containsTag(GpsDirectory.TAG_GPS_ALTITUDE) && gpsdir.containsTag(GpsDirectory.TAG_GPS_ALTITUDE_REF))
{
data.setAltitude(gpsdir.getRational(GpsDirectory.TAG_GPS_ALTITUDE).intValue());
byte altRef = (byte) gpsdir.getInt(GpsDirectory.TAG_GPS_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))
{
Rational[] times = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_TIME_STAMP);
data.setGpsTimestamp(new int[] {times[0].intValue(), times[1].intValue(),
times[2].intValue()});
Rational[] dates = gpsdir.getRationalArray(TAG_GPS_DATESTAMP);
data.setGpsDatestamp(new int[] {dates[0].intValue(), dates[1].intValue(), dates[2].intValue()});
}
}
// Tags from Exif directory
if (metadata.containsDirectory(ExifDirectory.class))
{
Directory exifdir = metadata.getDirectory(ExifDirectory.class);
// Take time and date from exif tags if haven't got it already from GPS
if (data.getGpsDatestamp() == null && exifdir.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
data.setOriginalTimestamp(exifdir.getString(ExifDirectory.TAG_DATETIME_ORIGINAL));
}
// Photo rotation code
if (exifdir.containsTag(ExifDirectory.TAG_ORIENTATION)) {
data.setOrientationCode(exifdir.getInt(ExifDirectory.TAG_ORIENTATION));
// NOTE: this presumably takes the _last_ orientation value found, not the first.
}
// Thumbnail
if (exifdir.containsTag(ExifDirectory.TAG_THUMBNAIL_DATA))
{
// Make a copy of the byte data rather than keeping a reference to extracted array
byte[] tdata = exifdir.getByteArray(ExifDirectory.TAG_THUMBNAIL_DATA);
byte[] thumb = new byte[tdata.length];
System.arraycopy(tdata, 0, thumb, 0, tdata.length);
data.setThumbnailImage(thumb);
}
}
}
catch (Exception e) {
// Exception reading metadata, just ignore it
}
return data;
}
/**
* Check whether the exifreader class can be correctly resolved
* @return true if it looks ok
*/
public boolean looksOK()
{
try {
String test = ExifReader.class.getName();
if (test != null) return true;
}
catch (LinkageError le) {}
return false;
}
}
|