Java Examples for org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants

The following java examples will help you to understand the usage of org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants. These source code samples are taken from different open source projects.

Example 1
Project: gopro2mapillary-master  File: EXIFPropertyReader.java View source code
public static long getDateTimeOriginal(File imageFile) throws ImageReadException, IOException, ParseException {
    final IImageMetadata metadata = Imaging.getMetadata(imageFile);
    final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
    String dateTimeOriginal = jpegMetadata.getExif().getFieldValue(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL)[0];
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
    return dateFormat.parse(dateTimeOriginal).getTime();
}
Example 2
Project: sanselan-master  File: TiffImageWriterBase.java View source code
protected TiffOutputSummary validateDirectories(TiffOutputSet outputSet) throws ImageWriteException {
    List<TiffOutputDirectory> directories = outputSet.getDirectories();
    if (1 > directories.size())
        throw new ImageWriteException("No directories.");
    TiffOutputDirectory exifDirectory = null;
    TiffOutputDirectory gpsDirectory = null;
    TiffOutputDirectory interoperabilityDirectory = null;
    TiffOutputField exifDirectoryOffsetField = null;
    TiffOutputField gpsDirectoryOffsetField = null;
    TiffOutputField interoperabilityDirectoryOffsetField = null;
    List<Integer> directoryIndices = new ArrayList<Integer>();
    Map<Integer, TiffOutputDirectory> directoryTypeMap = new HashMap<Integer, TiffOutputDirectory>();
    for (int i = 0; i < directories.size(); i++) {
        TiffOutputDirectory directory = directories.get(i);
        final int dirType = directory.type;
        directoryTypeMap.put(dirType, directory);
        if (dirType < 0) {
            switch(dirType) {
                case DIRECTORY_TYPE_EXIF:
                    if (exifDirectory != null)
                        throw new ImageWriteException("More than one EXIF directory.");
                    exifDirectory = directory;
                    break;
                case DIRECTORY_TYPE_GPS:
                    if (gpsDirectory != null)
                        throw new ImageWriteException("More than one GPS directory.");
                    gpsDirectory = directory;
                    break;
                case DIRECTORY_TYPE_INTEROPERABILITY:
                    if (interoperabilityDirectory != null)
                        throw new ImageWriteException("More than one Interoperability directory.");
                    interoperabilityDirectory = directory;
                    break;
                default:
                    throw new ImageWriteException("Unknown directory: " + dirType);
            }
        } else {
            if (directoryIndices.contains(dirType))
                throw new ImageWriteException("More than one directory with index: " + dirType + ".");
            directoryIndices.add(dirType);
        // dirMap.put(arg0, arg1)
        }
        HashSet<Integer> fieldTags = new HashSet<Integer>();
        List fields = directory.getFields();
        for (int j = 0; j < fields.size(); j++) {
            TiffOutputField field = (TiffOutputField) fields.get(j);
            if (fieldTags.contains(field.tag))
                throw new ImageWriteException("Tag (" + field.tagInfo.getDescription() + ") appears twice in directory.");
            fieldTags.add(field.tag);
            if (field.tag == ExifTagConstants.EXIF_TAG_EXIF_OFFSET.tag) {
                if (exifDirectoryOffsetField != null)
                    throw new ImageWriteException("More than one Exif directory offset field.");
                exifDirectoryOffsetField = field;
            } else if (field.tag == ExifTagConstants.EXIF_TAG_INTEROP_OFFSET.tag) {
                if (interoperabilityDirectoryOffsetField != null)
                    throw new ImageWriteException("More than one Interoperability directory offset field.");
                interoperabilityDirectoryOffsetField = field;
            } else if (field.tag == ExifTagConstants.EXIF_TAG_GPSINFO.tag) {
                if (gpsDirectoryOffsetField != null)
                    throw new ImageWriteException("More than one GPS directory offset field.");
                gpsDirectoryOffsetField = field;
            }
        }
    // directory.
    }
    if (directoryIndices.size() < 1)
        throw new ImageWriteException("Missing root directory.");
    // "normal" TIFF directories should have continous indices starting with
    // 0, ie. 0, 1, 2...
    Collections.sort(directoryIndices);
    TiffOutputDirectory previousDirectory = null;
    for (int i = 0; i < directoryIndices.size(); i++) {
        Integer index = directoryIndices.get(i);
        if (index.intValue() != i)
            throw new ImageWriteException("Missing directory: " + i + ".");
        // set up chain of directory references for "normal" directories.
        TiffOutputDirectory directory = directoryTypeMap.get(index);
        if (null != previousDirectory)
            previousDirectory.setNextDirectory(directory);
        previousDirectory = directory;
    }
    TiffOutputDirectory rootDirectory = directoryTypeMap.get(DIRECTORY_TYPE_ROOT);
    // prepare results
    TiffOutputSummary result = new TiffOutputSummary(byteOrder, rootDirectory, directoryTypeMap);
    if (interoperabilityDirectory == null && interoperabilityDirectoryOffsetField != null) {
        // perhaps we should just discard field?
        throw new ImageWriteException("Output set has Interoperability Directory Offset field, but no Interoperability Directory");
    } else if (interoperabilityDirectory != null) {
        if (exifDirectory == null) {
            exifDirectory = outputSet.addExifDirectory();
        }
        if (interoperabilityDirectoryOffsetField == null) {
            interoperabilityDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_INTEROP_OFFSET, byteOrder);
            exifDirectory.add(interoperabilityDirectoryOffsetField);
        }
        result.add(interoperabilityDirectory, interoperabilityDirectoryOffsetField);
    }
    // make sure offset fields and offset'd directories correspond.
    if (exifDirectory == null && exifDirectoryOffsetField != null) {
        // perhaps we should just discard field?
        throw new ImageWriteException("Output set has Exif Directory Offset field, but no Exif Directory");
    } else if (exifDirectory != null) {
        if (exifDirectoryOffsetField == null) {
            exifDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_EXIF_OFFSET, byteOrder);
            rootDirectory.add(exifDirectoryOffsetField);
        }
        result.add(exifDirectory, exifDirectoryOffsetField);
    }
    if (gpsDirectory == null && gpsDirectoryOffsetField != null) {
        // perhaps we should just discard field?
        throw new ImageWriteException("Output set has GPS Directory Offset field, but no GPS Directory");
    } else if (gpsDirectory != null) {
        if (gpsDirectoryOffsetField == null) {
            gpsDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_GPSINFO, byteOrder);
            rootDirectory.add(gpsDirectoryOffsetField);
        }
        result.add(gpsDirectory, gpsDirectoryOffsetField);
    }
    return result;
// Debug.debug();
}
Example 3
Project: DAT210-prosjekt-gruppe-D-master  File: MetadataExample.java View source code
public static void read(final File file) throws ImageReadException, IOException {
    // get all metadata stored in EXIF format (ie. from JPEG or TIFF).
    final IImageMetadata metadata = Imaging.getMetadata(file);
    if (metadata instanceof JpegImageMetadata) {
        final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
        System.out.println("file: " + file.getPath().replace("\\", "/"));
        printTagValue(jpegMetadata, TiffTagConstants.TIFF_TAG_XRESOLUTION);
        printTagValue(jpegMetadata, TiffTagConstants.TIFF_TAG_DATE_TIME);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_DATE_TIME_DIGITIZED);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_ISO);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_SHUTTER_SPEED_VALUE);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_APERTURE_VALUE);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_BRIGHTNESS_VALUE);
        printTagValue(jpegMetadata, GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
        printTagValue(jpegMetadata, GpsTagConstants.GPS_TAG_GPS_LATITUDE);
        printTagValue(jpegMetadata, GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
        printTagValue(jpegMetadata, GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
        System.out.println();
        // simple interface to GPS data
        final TiffImageMetadata exifMetadata = jpegMetadata.getExif();
        if (null != exifMetadata) {
            final TiffImageMetadata.GPSInfo gpsInfo = exifMetadata.getGPS();
            if (null != gpsInfo) {
                final String gpsDescription = gpsInfo.toString();
                final double longitude = gpsInfo.getLongitudeAsDegreesEast();
                final double latitude = gpsInfo.getLatitudeAsDegreesNorth();
                System.out.println("    " + "GPS Description: " + gpsDescription);
                System.out.println("    " + "GPS Longitude (Degrees East): " + longitude);
                System.out.println("    " + "GPS Latitude (Degrees North): " + latitude);
            }
        }
        // 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();
            final RationalNumber gpsLatitudeDegrees = gpsLatitude[0];
            final RationalNumber gpsLatitudeMinutes = gpsLatitude[1];
            final RationalNumber gpsLatitudeSeconds = gpsLatitude[2];
            final RationalNumber gpsLongitudeDegrees = gpsLongitude[0];
            final RationalNumber gpsLongitudeMinutes = gpsLongitude[1];
            final RationalNumber gpsLongitudeSeconds = gpsLongitude[2];
            // This will format the gps info like so:
            //
            // gpsLatitude: 8 degrees, 40 minutes, 42.2 seconds S
            // gpsLongitude: 115 degrees, 26 minutes, 21.8 seconds E
            System.out.println("    " + "GPS Latitude: " + gpsLatitudeDegrees.toDisplayString() + " degrees, " + gpsLatitudeMinutes.toDisplayString() + " minutes, " + gpsLatitudeSeconds.toDisplayString() + " seconds " + gpsLatitudeRef);
            System.out.println("    " + "GPS Longitude: " + gpsLongitudeDegrees.toDisplayString() + " degrees, " + gpsLongitudeMinutes.toDisplayString() + " minutes, " + gpsLongitudeSeconds.toDisplayString() + " seconds " + gpsLongitudeRef);
        }
        System.out.println();
        final List<IImageMetadataItem> items = jpegMetadata.getItems();
        for (int i = 0; i < items.size(); i++) {
            final IImageMetadataItem item = items.get(i);
            System.out.println("    item: " + item);
        }
        System.out.println();
        // print XMP data
        System.out.println(Imaging.getXmpXml(file));
    }
}
Example 4
Project: GeoTagPhotos-master  File: MetadataExample.java View source code
public static void metadataExample(final File file) throws ImageReadException, IOException {
    // get all metadata stored in EXIF format (ie. from JPEG or TIFF).
    final IImageMetadata metadata = Imaging.getMetadata(file);
    if (metadata instanceof JpegImageMetadata) {
        final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
        // Jpeg EXIF metadata is stored in a TIFF-based directory structure
        // and is identified with TIFF tags.
        // Here we look for the "x resolution" tag, but
        // we could just as easily search for any other tag.
        //
        // see the TiffConstants file for a list of TIFF tags.
        System.out.println("file: " + file.getPath());
        // print out various interesting EXIF tags.
        printTagValue(jpegMetadata, TiffTagConstants.TIFF_TAG_XRESOLUTION);
        printTagValue(jpegMetadata, TiffTagConstants.TIFF_TAG_DATE_TIME);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_DATE_TIME_DIGITIZED);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_ISO);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_SHUTTER_SPEED_VALUE);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_APERTURE_VALUE);
        printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_BRIGHTNESS_VALUE);
        printTagValue(jpegMetadata, GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
        printTagValue(jpegMetadata, GpsTagConstants.GPS_TAG_GPS_LATITUDE);
        printTagValue(jpegMetadata, GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
        printTagValue(jpegMetadata, GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
        System.out.println();
        // simple interface to GPS data
        final TiffImageMetadata exifMetadata = jpegMetadata.getExif();
        if (null != exifMetadata) {
            final TiffImageMetadata.GPSInfo gpsInfo = exifMetadata.getGPS();
            if (null != gpsInfo) {
                final String gpsDescription = gpsInfo.toString();
                final double longitude = gpsInfo.getLongitudeAsDegreesEast();
                final double latitude = gpsInfo.getLatitudeAsDegreesNorth();
                System.out.println("    " + "GPS Description: " + gpsDescription);
                System.out.println("    " + "GPS Longitude (Degrees East): " + longitude);
                System.out.println("    " + "GPS Latitude (Degrees North): " + latitude);
            }
        }
        // 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();
            final RationalNumber gpsLatitudeDegrees = gpsLatitude[0];
            final RationalNumber gpsLatitudeMinutes = gpsLatitude[1];
            final RationalNumber gpsLatitudeSeconds = gpsLatitude[2];
            final RationalNumber gpsLongitudeDegrees = gpsLongitude[0];
            final RationalNumber gpsLongitudeMinutes = gpsLongitude[1];
            final RationalNumber gpsLongitudeSeconds = gpsLongitude[2];
            // This will format the gps info like so:
            //
            // gpsLatitude: 8 degrees, 40 minutes, 42.2 seconds S
            // gpsLongitude: 115 degrees, 26 minutes, 21.8 seconds E
            System.out.println("    " + "GPS Latitude: " + gpsLatitudeDegrees.toDisplayString() + " degrees, " + gpsLatitudeMinutes.toDisplayString() + " minutes, " + gpsLatitudeSeconds.toDisplayString() + " seconds " + gpsLatitudeRef);
            System.out.println("    " + "GPS Longitude: " + gpsLongitudeDegrees.toDisplayString() + " degrees, " + gpsLongitudeMinutes.toDisplayString() + " minutes, " + gpsLongitudeSeconds.toDisplayString() + " seconds " + gpsLongitudeRef);
        }
        System.out.println();
        final List<IImageMetadataItem> items = jpegMetadata.getItems();
        for (int i = 0; i < items.size(); i++) {
            final IImageMetadataItem item = items.get(i);
            System.out.println("    " + "item: " + item);
        }
        System.out.println();
    }
}
Example 5
Project: smartly-master  File: TiffImageWriterBase.java View source code
protected TiffOutputSummary validateDirectories(final TiffOutputSet outputSet) throws ImageWriteException {
    final List<TiffOutputDirectory> directories = outputSet.getDirectories();
    if (1 > directories.size()) {
        throw new ImageWriteException("No directories.");
    }
    TiffOutputDirectory exifDirectory = null;
    TiffOutputDirectory gpsDirectory = null;
    TiffOutputDirectory interoperabilityDirectory = null;
    TiffOutputField exifDirectoryOffsetField = null;
    TiffOutputField gpsDirectoryOffsetField = null;
    TiffOutputField interoperabilityDirectoryOffsetField = null;
    final List<Integer> directoryIndices = new ArrayList<Integer>();
    final Map<Integer, TiffOutputDirectory> directoryTypeMap = new HashMap<Integer, TiffOutputDirectory>();
    for (int i = 0; i < directories.size(); i++) {
        final TiffOutputDirectory directory = directories.get(i);
        final int dirType = directory.type;
        directoryTypeMap.put(dirType, directory);
        if (dirType < 0) {
            switch(dirType) {
                case DIRECTORY_TYPE_EXIF:
                    if (exifDirectory != null) {
                        throw new ImageWriteException("More than one EXIF directory.");
                    }
                    exifDirectory = directory;
                    break;
                case DIRECTORY_TYPE_GPS:
                    if (gpsDirectory != null) {
                        throw new ImageWriteException("More than one GPS directory.");
                    }
                    gpsDirectory = directory;
                    break;
                case DIRECTORY_TYPE_INTEROPERABILITY:
                    if (interoperabilityDirectory != null) {
                        throw new ImageWriteException("More than one Interoperability directory.");
                    }
                    interoperabilityDirectory = directory;
                    break;
                default:
                    throw new ImageWriteException("Unknown directory: " + dirType);
            }
        } else {
            if (directoryIndices.contains(dirType)) {
                throw new ImageWriteException("More than one directory with index: " + dirType + ".");
            }
            directoryIndices.add(dirType);
        // dirMap.put(arg0, arg1)
        }
        final HashSet<Integer> fieldTags = new HashSet<Integer>();
        final List<TiffOutputField> fields = directory.getFields();
        for (int j = 0; j < fields.size(); j++) {
            final TiffOutputField field = fields.get(j);
            if (fieldTags.contains(field.tag)) {
                throw new ImageWriteException("Tag (" + field.tagInfo.getDescription() + ") appears twice in directory.");
            }
            fieldTags.add(field.tag);
            if (field.tag == ExifTagConstants.EXIF_TAG_EXIF_OFFSET.tag) {
                if (exifDirectoryOffsetField != null) {
                    throw new ImageWriteException("More than one Exif directory offset field.");
                }
                exifDirectoryOffsetField = field;
            } else if (field.tag == ExifTagConstants.EXIF_TAG_INTEROP_OFFSET.tag) {
                if (interoperabilityDirectoryOffsetField != null) {
                    throw new ImageWriteException("More than one Interoperability directory offset field.");
                }
                interoperabilityDirectoryOffsetField = field;
            } else if (field.tag == ExifTagConstants.EXIF_TAG_GPSINFO.tag) {
                if (gpsDirectoryOffsetField != null) {
                    throw new ImageWriteException("More than one GPS directory offset field.");
                }
                gpsDirectoryOffsetField = field;
            }
        }
    // directory.
    }
    if (directoryIndices.size() < 1) {
        throw new ImageWriteException("Missing root directory.");
    }
    // "normal" TIFF directories should have continous indices starting with
    // 0, ie. 0, 1, 2...
    Collections.sort(directoryIndices);
    TiffOutputDirectory previousDirectory = null;
    for (int i = 0; i < directoryIndices.size(); i++) {
        final Integer index = directoryIndices.get(i);
        if (index.intValue() != i) {
            throw new ImageWriteException("Missing directory: " + i + ".");
        }
        // set up chain of directory references for "normal" directories.
        final TiffOutputDirectory directory = directoryTypeMap.get(index);
        if (null != previousDirectory) {
            previousDirectory.setNextDirectory(directory);
        }
        previousDirectory = directory;
    }
    final TiffOutputDirectory rootDirectory = directoryTypeMap.get(DIRECTORY_TYPE_ROOT);
    // prepare results
    final TiffOutputSummary result = new TiffOutputSummary(byteOrder, rootDirectory, directoryTypeMap);
    if (interoperabilityDirectory == null && interoperabilityDirectoryOffsetField != null) {
        // perhaps we should just discard field?
        throw new ImageWriteException("Output set has Interoperability Directory Offset field, but no Interoperability Directory");
    } else if (interoperabilityDirectory != null) {
        if (exifDirectory == null) {
            exifDirectory = outputSet.addExifDirectory();
        }
        if (interoperabilityDirectoryOffsetField == null) {
            interoperabilityDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_INTEROP_OFFSET, byteOrder);
            exifDirectory.add(interoperabilityDirectoryOffsetField);
        }
        result.add(interoperabilityDirectory, interoperabilityDirectoryOffsetField);
    }
    // make sure offset fields and offset'd directories correspond.
    if (exifDirectory == null && exifDirectoryOffsetField != null) {
        // perhaps we should just discard field?
        throw new ImageWriteException("Output set has Exif Directory Offset field, but no Exif Directory");
    } else if (exifDirectory != null) {
        if (exifDirectoryOffsetField == null) {
            exifDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_EXIF_OFFSET, byteOrder);
            rootDirectory.add(exifDirectoryOffsetField);
        }
        result.add(exifDirectory, exifDirectoryOffsetField);
    }
    if (gpsDirectory == null && gpsDirectoryOffsetField != null) {
        // perhaps we should just discard field?
        throw new ImageWriteException("Output set has GPS Directory Offset field, but no GPS Directory");
    } else if (gpsDirectory != null) {
        if (gpsDirectoryOffsetField == null) {
            gpsDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_GPSINFO, byteOrder);
            rootDirectory.add(gpsDirectoryOffsetField);
        }
        result.add(gpsDirectory, gpsDirectoryOffsetField);
    }
    return result;
// Debug.debug();
}
Example 6
Project: Augendiagnose-master  File: JpegMetadataUtil.java View source code
/**
	 * Retrieve the relevant metadata of an image file.
	 *
	 * @param jpegImageFileName the file for which metadata should be retrieved.
	 * @return the metadata of the file.
	 * @throws ImageReadException thrown if the metadata cannot be read.
	 * @throws IOException        thrown in case of other errors while reading metadata.
	 */
@NonNull
public static JpegMetadata getMetadata(@NonNull final String jpegImageFileName) throws ImageReadException, IOException {
    checkJpeg(jpegImageFileName);
    JpegMetadata result = new JpegMetadata();
    final File imageFile = new File(jpegImageFileName);
    // Retrieve XMP data
    String xmpString = Imaging.getXmpXml(imageFile);
    XmpHandler parser = new XmpHandler(xmpString);
    // Standard fields are pre-filled with custom data
    result.setTitle(parser.getJeItem(XmpHandler.ITEM_TITLE));
    result.setDescription(parser.getJeItem(XmpHandler.ITEM_DESCRIPTION));
    result.setSubject(parser.getJeItem(XmpHandler.ITEM_SUBJECT));
    result.setComment(parser.getJeItem(XmpHandler.ITEM_COMMENT));
    result.setPerson(parser.getJeItem(XmpHandler.ITEM_PERSON));
    result.setXCenter(parser.getJeItem(XmpHandler.ITEM_X_CENTER));
    result.setYCenter(parser.getJeItem(XmpHandler.ITEM_Y_CENTER));
    result.setOverlayScaleFactor(parser.getJeItem(XmpHandler.ITEM_OVERLAY_SCALE_FACTOR));
    result.setXPosition(parser.getJeItem(XmpHandler.ITEM_X_POSITION));
    result.setYPosition(parser.getJeItem(XmpHandler.ITEM_Y_POSITION));
    result.setZoomFactor(parser.getJeItem(XmpHandler.ITEM_ZOOM_FACTOR));
    result.setOrganizeDate(parser.getJeDate(XmpHandler.ITEM_ORGANIZE_DATE));
    result.setRightLeft(parser.getJeItem(XmpHandler.ITEM_RIGHT_LEFT));
    result.setBrightness(parser.getJeItem(XmpHandler.ITEM_BRIGHTNESS));
    result.setContrast(parser.getJeItem(XmpHandler.ITEM_CONTRAST));
    result.setSaturation(parser.getJeItem(XmpHandler.ITEM_SATURATION));
    result.setColorTemperature(parser.getJeItem(XmpHandler.ITEM_COLOR_TEMPERATURE));
    result.setOverlayColor(parser.getJeItem(XmpHandler.ITEM_OVERLAY_COLOR));
    result.setPupilSize(parser.getJeItem(XmpHandler.ITEM_PUPIL_SIZE));
    result.setPupilXOffset(parser.getJeItem(XmpHandler.ITEM_PUPIL_X_OFFSET));
    result.setPupilYOffset(parser.getJeItem(XmpHandler.ITEM_PUPIL_Y_OFFSET));
    result.setFlags(parser.getJeInt(XmpHandler.ITEM_FLAGS));
    // For standard fields, use custom data only if there is no other data.
    if (result.getDescription() == null) {
        result.setDescription(parser.getDcDescription());
    }
    if (result.getSubject() == null) {
        result.setSubject(parser.getDcSubject());
    }
    if (result.getPerson() == null) {
        result.setPerson(parser.getMicrosoftPerson());
    }
    if (result.getTitle() == null) {
        result.setTitle(parser.getDcTitle());
    }
    if (result.getComment() == null) {
        result.setComment(parser.getUserComment());
    }
    // Retrieve EXIF data
    try {
        final IImageMetadata metadata = Imaging.getMetadata(imageFile);
        TiffImageMetadata tiffImageMetadata;
        if (metadata instanceof JpegImageMetadata) {
            tiffImageMetadata = ((JpegImageMetadata) metadata).getExif();
        } else if (metadata instanceof TiffImageMetadata) {
            tiffImageMetadata = (TiffImageMetadata) metadata;
        } else {
            return result;
        }
        // EXIF data have precedence only if saving EXIF is allowed
        TiffField title = tiffImageMetadata.findField(TiffTagConstants.TIFF_TAG_IMAGE_DESCRIPTION);
        if (title != null && (changeExifAllowed() || result.getTitle() == null)) {
            result.setTitle(title.getStringValue().trim());
        }
        String exifComment = null;
        TiffField comment = tiffImageMetadata.findField(ExifTagConstants.EXIF_TAG_USER_COMMENT);
        if (comment != null && comment.getStringValue().trim().length() > 0) {
            exifComment = comment.getStringValue().trim();
        }
        TiffField comment2 = tiffImageMetadata.findField(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT);
        if (comment2 != null && comment2.getStringValue().trim().length() > 0) {
            // XPComment takes precedence if existing
            exifComment = comment2.getStringValue().trim();
        }
        if (exifComment != null && (changeExifAllowed() || result.getComment() == null)) {
            result.setComment(exifComment);
        }
        TiffField subject = tiffImageMetadata.findField(MicrosoftTagConstants.EXIF_TAG_XPSUBJECT);
        if (subject != null && (changeExifAllowed() || result.getSubject() == null)) {
            result.setSubject(subject.getStringValue().trim());
        }
    } catch (Exception e) {
        Log.w(Application.TAG, "Error when retrieving Exif data", e);
    }
    // If fields are still null, try to get them from custom XMP
    if (result.getDescription() == null) {
        result.setDescription(parser.getJeItem(XmpHandler.ITEM_DESCRIPTION));
    }
    if (result.getSubject() == null) {
        result.setSubject(parser.getJeItem(XmpHandler.ITEM_SUBJECT));
    }
    if (result.getPerson() == null) {
        result.setPerson(parser.getJeItem(XmpHandler.ITEM_PERSON));
    }
    if (result.getTitle() == null) {
        result.setTitle(parser.getJeItem(XmpHandler.ITEM_TITLE));
    }
    if (result.getComment() == null) {
        result.setComment(parser.getJeItem(XmpHandler.ITEM_COMMENT));
    }
    return result;
}