Java tutorial
/* * Weblounge: Web Content Management System * Copyright (c) 2003 - 2011 The Weblounge Team * http://entwinemedia.com/weblounge * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package ch.entwine.weblounge.common.impl.content.image; import com.drew.imaging.ImageMetadataReader; import com.drew.imaging.ImageProcessingException; import com.drew.lang.Rational; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataException; import com.drew.metadata.exif.ExifDirectory; import com.drew.metadata.exif.GpsDirectory; import com.drew.metadata.iptc.IptcDirectory; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.StringTokenizer; /** * Utility class for dealing with image meta data */ public final class ImageMetadataUtils { /** The logging facility */ private static Logger logger = LoggerFactory.getLogger(ImageMetadataUtils.class); /** * This class is not meant to be instantiated. */ private ImageMetadataUtils() { // Utility classes should not have a public or default constructor } /** * This utility method extracts image metadata stored in EXIF and IPTC tags * and returns the extracted information in a {@link ImageMetadata}. * * @param img * image file * @return extracted meta information */ public static ImageMetadata extractMetadata(File img) { BufferedInputStream is = null; try { is = new BufferedInputStream(new FileInputStream(img)); return extractMetadata(is); } catch (FileNotFoundException e) { logger.warn("Tried to extract image metadata from none existing file '{}'", img.getName()); return null; } finally { IOUtils.closeQuietly(is); } } /** * This utility method extracts image metadata stored in EXIF and IPTC tags * and returns the extracted information in a {@link ImageMetadata}. * * @param img * image input stream * @return extracted meta information */ public static ImageMetadata extractMetadata(BufferedInputStream img) { Metadata meta; try { meta = ImageMetadataReader.readMetadata(img); } catch (ImageProcessingException e) { if ("File is not the correct format".equals(e.getMessage())) return null; logger.warn("Failed to extract image metadata from image: {}", e.getMessage()); return null; } if (meta == null) { logger.debug("Extracted metadata is null"); return null; } else { ImageMetadata imgmeta = new ImageMetadata(); // Extract IPTC information Directory iptc = meta.getDirectory(IptcDirectory.class); if (iptc.containsTag(IptcDirectory.TAG_HEADLINE)) imgmeta.setCaption(iptc.getString(IptcDirectory.TAG_HEADLINE)); if (iptc.containsTag(IptcDirectory.TAG_CAPTION)) imgmeta.setLegend(iptc.getString(IptcDirectory.TAG_CAPTION)); if (iptc.containsTag(IptcDirectory.TAG_BY_LINE)) imgmeta.setPhotographer(iptc.getString(IptcDirectory.TAG_BY_LINE)); if (iptc.containsTag(IptcDirectory.TAG_COPYRIGHT_NOTICE)) imgmeta.setCopyright(iptc.getString(IptcDirectory.TAG_COPYRIGHT_NOTICE)); if (iptc.containsTag(IptcDirectory.TAG_CITY)) imgmeta.setLocation(iptc.getString(IptcDirectory.TAG_CITY)); if (iptc.containsTag(IptcDirectory.TAG_KEYWORDS)) { StringTokenizer st = new StringTokenizer(iptc.getString(IptcDirectory.TAG_KEYWORDS), ",;"); while (st.hasMoreTokens()) { imgmeta.addKeyword(st.nextToken()); } } // Extract EXIF information Directory exif = meta.getDirectory(ExifDirectory.class); if (exif.containsTag(ExifDirectory.TAG_DATETIME)) { try { imgmeta.setDateTaken(exif.getDate(ExifDirectory.TAG_DATETIME)); } catch (MetadataException e) { } } if (exif.containsTag(ExifDirectory.TAG_ISO_EQUIVALENT)) { try { imgmeta.setFilmspeed(exif.getInt(ExifDirectory.TAG_ISO_EQUIVALENT)); } catch (MetadataException e) { } } if (exif.containsTag(ExifDirectory.TAG_FNUMBER)) { try { imgmeta.setFNumber(exif.getFloat(ExifDirectory.TAG_FNUMBER)); } catch (MetadataException e) { } } if (exif.containsTag(ExifDirectory.TAG_FOCAL_LENGTH)) { try { imgmeta.setFocalWidth(exif.getInt(ExifDirectory.TAG_FOCAL_LENGTH)); } catch (MetadataException e) { } } if (exif.containsTag(ExifDirectory.TAG_EXPOSURE_TIME)) { try { imgmeta.setExposureTime(exif.getFloat(ExifDirectory.TAG_EXPOSURE_TIME)); } catch (MetadataException e) { } } if (StringUtils.isBlank(imgmeta.getCopyright()) && exif.containsTag(ExifDirectory.TAG_COPYRIGHT)) imgmeta.setCopyright(exif.getString(ExifDirectory.TAG_COPYRIGHT)); // Extract GPS information try { Directory gps = meta.getDirectory(GpsDirectory.class); if (gps.containsTag(GpsDirectory.TAG_GPS_LATITUDE)) { Rational[] lat = gps.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE); String latRef = gps.getString(GpsDirectory.TAG_GPS_LATITUDE_REF); double latitude = parseHMS(lat); if (latitude != 0) { if (StringUtils.isNotBlank(latRef) && "S".equalsIgnoreCase(latRef) && latitude > 0) latitude *= -1; } imgmeta.setGpsLat(latitude); } if (gps.containsTag(GpsDirectory.TAG_GPS_LONGITUDE)) { Rational[] lng = gps.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE); String lngRef = gps.getString(GpsDirectory.TAG_GPS_LONGITUDE_REF); double longitude = parseHMS(lng); if (longitude != 0) { if (StringUtils.isNotBlank(lngRef) && "W".equalsIgnoreCase(lngRef) && longitude > 0) longitude *= -1; } imgmeta.setGpsLong(longitude); } } catch (MetadataException e) { logger.info("Error while extracting GPS information out of an image."); imgmeta.setGpsLat(0); imgmeta.setGpsLong(0); } return imgmeta; } } private static double parseHMS(Rational[] hms) { return hms[0].doubleValue() + (hms[1].doubleValue() + (hms[2].doubleValue() / 60)) / 60; } }