package com.totsp.imageio; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import org.apache.commons.io.FileUtils; import org.cmc.sanselan.ImageReadException; import org.cmc.sanselan.ImageWriteException; import org.cmc.sanselan.Sanselan; import org.cmc.sanselan.common.IImageMetadata; import org.cmc.sanselan.formats.jpeg.JpegImageMetadata; import org.cmc.sanselan.formats.jpeg.exifRewrite.ExifRewriter; import org.cmc.sanselan.formats.tiff.TiffField; import org.cmc.sanselan.formats.tiff.TiffImageMetadata; import org.cmc.sanselan.formats.tiff.constants.ExifTagConstants; import org.cmc.sanselan.formats.tiff.constants.TagInfo; import org.cmc.sanselan.formats.tiff.constants.TiffConstants; import org.cmc.sanselan.formats.tiff.constants.TiffFieldTypeConstants; import org.cmc.sanselan.formats.tiff.write.TiffOutputDirectory; import org.cmc.sanselan.formats.tiff.write.TiffOutputField; import org.cmc.sanselan.formats.tiff.write.TiffOutputSet; /** * Sanselan demo, borrowing from Sanselan docs/demos. * http://www.fightingquaker.com/sanselan/ * * @author ccollins * */ public class SanselanDemo { /** * Read metadata from image file and display it. * * @param file */ public void readMetaData(File file) { IImageMetadata metadata = null; try { metadata = Sanselan.getMetadata(file); } catch (ImageReadException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (metadata instanceof JpegImageMetadata) { JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata; System.out.println("\nFile: " + file.getPath()); printTagValue(jpegMetadata, TiffConstants.TIFF_TAG_XRESOLUTION); printTagValue(jpegMetadata, TiffConstants.TIFF_TAG_DATE_TIME); printTagValue(jpegMetadata, TiffConstants.EXIF_TAG_DATE_TIME_ORIGINAL); printTagValue(jpegMetadata, TiffConstants.EXIF_TAG_CREATE_DATE); printTagValue(jpegMetadata, TiffConstants.EXIF_TAG_ISO); printTagValue(jpegMetadata, TiffConstants.EXIF_TAG_SHUTTER_SPEED_VALUE); printTagValue(jpegMetadata, TiffConstants.EXIF_TAG_APERTURE_VALUE); printTagValue(jpegMetadata, TiffConstants.EXIF_TAG_BRIGHTNESS_VALUE); // simple interface to GPS data TiffImageMetadata exifMetadata = jpegMetadata.getExif(); if (null != exifMetadata) { try { TiffImageMetadata.GPSInfo gpsInfo = exifMetadata.getGPS(); if (null != gpsInfo) { double longitude = gpsInfo.getLongitudeAsDegreesEast(); double latitude = gpsInfo.getLatitudeAsDegreesNorth(); System.out.println(" " + "GPS Description: " + gpsInfo); System.out.println(" " + "GPS Longitude (Degrees East): " + longitude); System.out.println(" " + "GPS Latitude (Degrees North): " + latitude); } } catch (ImageReadException e) { e.printStackTrace(); } } System.out.println("EXIF items -"); ArrayList items = jpegMetadata.getItems(); for (int i = 0; i < items.size(); i++) { Object item = items.get(i); System.out.println(" " + "item: " + item); } System.out.println(); } } private static void printTagValue( JpegImageMetadata jpegMetadata, TagInfo tagInfo) { TiffField field = jpegMetadata.findEXIFValue(tagInfo); if (field == null) { System.out.println(tagInfo.name + ": " + "Not Found."); } else { System.out.println(tagInfo.name + ": " + field.getValueDescription()); } } /** * Example of adding an EXIF item to metadata, in this case using ImageHistory field. * (I have no idea if this is an appropriate use of ImageHistory, or not, just picked * a field to update that looked like it wasn't commonly mucked with.) * * @param file */ public void addImageHistoryTag(File file) { File dst = null; IImageMetadata metadata = null; JpegImageMetadata jpegMetadata = null; TiffImageMetadata exif = null; OutputStream os = null; TiffOutputSet outputSet = new TiffOutputSet(); // establish metadata try { metadata = Sanselan.getMetadata(file); } catch (ImageReadException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // establish jpegMedatadata if (metadata != null) { jpegMetadata = (JpegImageMetadata) metadata; } // establish exif if (jpegMetadata != null) { exif = jpegMetadata.getExif(); } // establish outputSet if (exif != null) { try { outputSet = exif.getOutputSet(); } catch (ImageWriteException e) { e.printStackTrace(); } } if (outputSet != null) { // check if field already EXISTS - if so remove TiffOutputField imageHistoryPre = outputSet .findField(TiffConstants.EXIF_TAG_IMAGE_HISTORY); if (imageHistoryPre != null) { outputSet.removeField(TiffConstants.EXIF_TAG_IMAGE_HISTORY); } // add field try { String fieldData = "ImageHistory-" + System.currentTimeMillis(); TiffOutputField imageHistory = new TiffOutputField(ExifTagConstants.EXIF_TAG_IMAGE_HISTORY, TiffFieldTypeConstants.FIELD_TYPE_ASCII, fieldData.length(), fieldData.getBytes()); TiffOutputDirectory exifDirectory = outputSet.getOrCreateExifDirectory(); exifDirectory.add(imageHistory); } catch (ImageWriteException e) { e.printStackTrace(); } } // create stream using temp file for dst try { dst = File.createTempFile("temp-" + System.currentTimeMillis(), ".jpeg"); os = new FileOutputStream(dst); os = new BufferedOutputStream(os); } catch (IOException e) { e.printStackTrace(); } // write/update EXIF metadata to output stream try { new ExifRewriter().updateExifMetadataLossless(file, os, outputSet); } catch (ImageReadException e) { e.printStackTrace(); } catch (ImageWriteException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (os != null) { try { os.close(); } catch (IOException e) { } } } // copy temp file over original file try { FileUtils.copyFile(dst, file); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { File bikeFile = new File("data/bike.jpg"); SanselanDemo demo = new SanselanDemo(); System.out.println("BEFORE update"); demo.readMetaData(bikeFile); demo.addImageHistoryTag(bikeFile); System.out.println("\nAFTER update"); demo.readMetaData(bikeFile); } }