Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package lucee.runtime.img; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; import lucee.commons.io.IOUtil; import lucee.commons.io.res.Resource; import lucee.commons.io.res.ResourcesImpl; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.StringUtil; import lucee.runtime.op.Decision; import lucee.runtime.type.Array; import lucee.runtime.type.ArrayImpl; import lucee.runtime.type.Struct; import lucee.runtime.type.StructImpl; 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.common.ImageMetadata.Item; import org.apache.commons.imaging.common.RationalNumber; import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata; import org.apache.commons.imaging.formats.jpeg.JpegPhotoshopMetadata; import org.apache.commons.imaging.formats.tiff.TiffField; import org.apache.commons.imaging.formats.tiff.TiffImageMetadata; import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants; import org.apache.commons.imaging.formats.tiff.taginfos.TagInfo; public class Metadata { public static void main(String[] args) { Resource res = ResourcesImpl.getFileResourceProvider() .getResource("/Users/mic/Projects/Lucee/Lucee5/test/functions/images/BigBen.jpg"); Struct info = new StructImpl(); addInfo("jpg", res, info); } public static void addExifInfo(String format, final Resource res, Struct info) { InputStream is = null; try { is = res.getInputStream(); fillExif(format, is, info); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } finally { IOUtil.closeEL(is); } } private static void fillExif(String format, InputStream is, Struct info) throws ImageReadException, IOException { // get all metadata stored in EXIF format (ie. from JPEG or TIFF). IImageMetadata metadata = Imaging.getMetadata(is, "test." + format); if (metadata == null) return; if (metadata instanceof JpegImageMetadata) { final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata; // EXIF if (jpegMetadata != null) { try { set(jpegMetadata.getExif().getItems(), info, null); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } } // GPS try { gps(jpegMetadata, info); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } } } public static void addInfo(String format, final Resource res, Struct info) { InputStream is = null; try { is = res.getInputStream(); fill(format, is, info); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } finally { IOUtil.closeEL(is); } } private static void fill(String format, InputStream is, Struct info) throws ImageReadException, IOException { // get all metadata stored in EXIF format (ie. from JPEG or TIFF). IImageMetadata metadata = Imaging.getMetadata(is, "test." + format); if (metadata == null) return; // System.out.println(metadata); if (metadata instanceof JpegImageMetadata) { final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata; try { set(jpegMetadata.getItems(), info, null); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } try { set(metadata.getItems(), info, null); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } // Photoshop if (metadata instanceof JpegImageMetadata) { JpegPhotoshopMetadata photoshop = ((JpegImageMetadata) metadata).getPhotoshop(); if (photoshop != null) { try { List<? extends IImageMetadataItem> list = photoshop.getItems(); if (list != null && !list.isEmpty()) { Struct ps = new StructImpl(); info.setEL("photoshop", ps); try { set(list, ps, null); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } } } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } } } // EXIF if (jpegMetadata != null) { Struct exif = new StructImpl(); info.setEL("exif", exif); try { set(jpegMetadata.getExif().getItems(), exif, null); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } } // GPS try { gps(jpegMetadata, info); } catch (Throwable t) { ExceptionUtil.rethrowIfNecessary(t); } } } private static void gps(JpegImageMetadata jpegMetadata, Struct info) throws ImageReadException { Struct gps = new StructImpl(); info.setEL("gps", gps); info = gps; final TiffImageMetadata exifMetadata = jpegMetadata.getExif(); Double longitude = null; Double latitude = null; if (null != exifMetadata) { final TiffImageMetadata.GPSInfo gpsInfo = exifMetadata.getGPS(); if (null != gpsInfo) { //final String gpsDescription = gpsInfo.toString(); longitude = gpsInfo.getLongitudeAsDegreesEast(); latitude = gpsInfo.getLatitudeAsDegreesNorth(); } } // more specific example of how to manually access GPS values final TiffField gpsLatitudeRefField = jpegMetadata .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF); final TiffField gpsLatitudeField = jpegMetadata .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE); final TiffField gpsLongitudeRefField = jpegMetadata .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF); final TiffField gpsLongitudeField = jpegMetadata .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE); if (gpsLatitudeRefField != null && gpsLatitudeField != null && gpsLongitudeRefField != null && gpsLongitudeField != null) { // all of these values are strings. final String gpsLatitudeRef = (String) gpsLatitudeRefField.getValue(); final RationalNumber gpsLatitude[] = (RationalNumber[]) (gpsLatitudeField.getValue()); final String gpsLongitudeRef = (String) gpsLongitudeRefField.getValue(); final RationalNumber gpsLongitude[] = (RationalNumber[]) gpsLongitudeField.getValue(); info.setEL("GPS Latitude", gpsLatitude[0].toDisplayString() + "\"" + gpsLatitude[1].toDisplayString() + "'" + gpsLatitude[2].toDisplayString()); info.setEL("GPS Latitude Ref", gpsLatitudeRef); Struct sct = new StructImpl(); gps.setEL("latitude", sct); sct.setEL("degrees", gpsLatitude[0].doubleValue()); sct.setEL("minutes", gpsLatitude[1].doubleValue()); sct.setEL("seconds", gpsLatitude[2].doubleValue()); sct.setEL("ref", gpsLatitudeRef); sct.setEL("decimal", latitude); info.setEL("GPS Longitude", gpsLongitude[0].toDisplayString() + "\"" + gpsLongitude[1].toDisplayString() + "'" + gpsLongitude[2].toDisplayString()); info.setEL("GPS Longitude Ref", gpsLongitudeRef); sct = new StructImpl(); gps.setEL("longitude", sct); sct.setEL("degrees", gpsLongitude[0].doubleValue()); sct.setEL("minutes", gpsLongitude[1].doubleValue()); sct.setEL("seconds", gpsLongitude[2].doubleValue()); sct.setEL("ref", gpsLongitudeRef); sct.setEL("decimal", longitude); } } private static void set(Struct sct1, Struct sct2, String name1, String name2, Object value) { if (value instanceof CharSequence) value = StringUtil.unwrap(value.toString()); sct1.setEL(name1, value); sct2.setEL(name2, value); } private static Object val(Object value) { if (value == null) return null; if (value instanceof CharSequence) return value.toString(); if (value instanceof Number) return ((Number) value).doubleValue(); if (Decision.isNativeArray(value) && !(value instanceof Object[])) return value; if (value instanceof Object[]) { Array trg = new ArrayImpl(); Object[] arr = (Object[]) value; for (Object obj : arr) { trg.appendEL(val(obj)); } return trg; } if (value instanceof RationalNumber) { RationalNumber rn = (RationalNumber) value; return rn.toDisplayString(); } return value; } private static void set(List<? extends IImageMetadataItem> items, Struct data1, Struct data2) { Iterator<? extends IImageMetadataItem> it = items.iterator(); Item item; while (it.hasNext()) { item = (Item) it.next(); data1.setEL(item.getKeyword(), StringUtil.unwrap(item.getText())); if (data2 != null) data2.setEL(item.getKeyword(), StringUtil.unwrap(item.getText())); } } private static void set(final JpegImageMetadata jpegMetadata, final TagInfo tagInfo, Struct info) throws ImageReadException { final TiffField field = jpegMetadata.findEXIFValueWithExactMatch(tagInfo); if (field != null) { if (!info.containsKey(tagInfo.name)) { Object val = val(field.getValue()); if (val != null) info.setEL(tagInfo.name, val); } } } }