Read Image Metadata from single file with Java

27,488

Solution 1

You haven't specified the path to the file correctly. The change below should indicate this!

public static void main(String[] args) {
    Metadata meta = new Metadata();
    int length = args.length;
    for ( int i = 0; i < length; i++ ) {
        if (new File(args[i]).exists()) {
            meta.readAndDisplayMetadata( args[i] );
        } else {
            System.out.println("cannot find file: " + args[i]);
        }
    }
}

EDIT - Simpler code example

We are now statically defining which file to use.

public static void main(String[] args) {
    Metadata meta = new Metadata();
    String filename = "C:\\Users\\luckheart\\Pictures\\Sample Pictures\\Koala.jpg";
    if (new File(filename).exists()) {
        meta.readAndDisplayMetadata(filename);
    } else {
        System.out.println("cannot find file: " + filename);
    }
}

Solution 2

Reading Image Meta is now much simplified and streamlined with apache commons-imaging library

/**
 * Reference : https://github.com/apache/commons-imaging/blob/master/src/test/java/org/apache/commons/imaging/examples/MetadataExample.java
 */
public static void readImageMeta(final File imgFile) throws ImageReadException, IOException {
    /** get all metadata stored in EXIF format (ie. from JPEG or TIFF). **/
    final ImageMetadata metadata = Imaging.getMetadata(imgFile);
    System.out.println(metadata);
    System.out.println("--------------------------------------------------------------------------------");
    
    /** Get specific meta data information by drilling down the meta **/
    if (metadata instanceof JpegImageMetadata) {
        JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
        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);
        
        // 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);
        }
    }
}

private static void printTagValue(final JpegImageMetadata jpegMetadata, TagInfo tagInfo) {
    final TiffField field = jpegMetadata.findEXIFValueWithExactMatch(tagInfo);
    if (field == null) {
        System.out.println(tagInfo.name + ": " + "Not Found.");
    } else {
        System.out.println(tagInfo.name + ": " + field.getValueDescription());
    }
}


public static void main(String[] args) throws IOException, ImageReadException {
    File sourceFile = new File("/Users/vivek/myimage.jpg");
    readImageMeta(sourceFile);
}

The above code will give this output

Exif metadata:
    Root: 
        ImageWidth: 3024
        ImageLength: 4032
        BitsPerSample: 8, 8, 8
        PhotometricInterpretation: 2
        Make: 'Apple'
        Model: 'iPhone 6s'
        Orientation: 1
        SamplesPerPixel: 3
        XResolution: 72
        YResolution: 72
        ResolutionUnit: 2
        Software: 'Adobe Photoshop CC 2015 (Macintosh)'
        DateTime: '2016:05:17 16:55:55'
        YCbCrPositioning: 1
        ExifOffset: 300
        GPSInfo: 868

    Exif: 
        ExposureTime: 1/100 (0.01)
        FNumber: 11/5 (2.2)
        ExposureProgram: 2
        PhotographicSensitivity: 40
        ExifVersion: 48, 50, 50, 49
        DateTimeOriginal: '2016:05:08 18:03:57'
        DateTimeDigitized: '2016:05:08 18:03:57'
        ComponentsConfiguration: 1, 2, 3, 0
        ShutterSpeedValue: 35113/5284 (6.645)
        ApertureValue: 7983/3509 (2.275)
        BrightnessValue: 13026/2395 (5.439)
        ExposureCompensation: 0
        MeteringMode: 5
        Flash: 16
        FocalLength: 83/20 (4.15)
        SubjectArea: 618, 1555, 310, 311
        SubSecTimeOriginal: '523'
        SubSecTimeDigitized: '523'
        FlashpixVersion: 48, 49, 48, 48
        ColorSpace: 1
        ExifImageWidth: 3024
        ExifImageLength: 4032
        SensingMethod: 2
        SceneType: 1
        CustomRendered: 4
        ExposureMode: 0
        WhiteBalance: 0
        FocalLengthIn35mmFormat: 29
        SceneCaptureType: 0
        LensSpecification: 83/20 (4.15), 83/20 (4.15), 11/5 (2.2), 11/5 (2.2)
        LensMake: 'Apple'
        LensModel: 'iPhone 6s back camera 4.15mm f/2.2'

    Gps: 
        GPSLatitudeRef: 'N'
        GPSLatitude: 13, 21, 3305/100 (33.05)
        GPSLongitudeRef: 'E'
        GPSLongitude: 75, 33, 2034/100 (20.34)
        GPSAltitudeRef: 0
        GPSAltitude: 83651/95 (880.537)
        GPSTimeStamp: 12, 33, 57
        GPSSpeedRef: 'K'
        GPSSpeed: 21/100 (0.21)
        GPSImgDirectionRef: 'T'
        GPSImgDirection: 1654/31 (53.355)
        GPSDestBearingRef: 'T'
        GPSDestBearing: 1654/31 (53.355)
        GPSDateStamp: '2016:05:08'
        Unknown Tag (0x1f): 5

    Sub:  (jpegImageData)
        Compression: 6
        XResolution: 72
        YResolution: 72
        ResolutionUnit: 2
        JpgFromRawStart: 1274
        JpgFromRawLength: 8211

Photoshop (IPTC) metadata:
        Date Created: 20160508
        Time Created: 180357+0000
--------------------------------------------------------------------------------
GPSLatitudeRef: 'N'
GPSLatitude: 13, 21, 3305/100 (33.05)
GPSLongitudeRef: 'E'
GPSLongitude: 75, 33, 2034/100 (20.34)
    GPS Description: [GPS. Latitude: 13 degrees, 21 minutes, 33.05 seconds N, Longitude: 75 degrees, 33 minutes, 20.34 seconds E]
    GPS Longitude (Degrees East): 75.55565
    GPS Latitude (Degrees North): 13.359180555555556
    GPS Latitude: 13 degrees, 21 minutes, 33.05 seconds N
    GPS Longitude: 75 degrees, 33 minutes, 20.34 seconds E

Fore More Refer the library documentation here
Maven Repo Link here.
Note : It's an alpha release at this time but you can trust apache :D.

Cheers!

Share:
27,488
Luckheart
Author by

Luckheart

Updated on October 25, 2021

Comments

  • Luckheart
    Luckheart over 2 years

    I want to read image metadata from a single file. I tried the following code:

    http://johnbokma.com/java/obtaining-image-metadata.html

    When I run it, I get build successful but nothing happens.

    public class Metadata {
    
        public static void main(String[] args) {
            Metadata meta = new Metadata();
            int length = args.length;
            for ( int i = 0; i < length; i++ )
            meta.readAndDisplayMetadata( args[i] );
        }
    
        void readAndDisplayMetadata( String fileName ) {
            try {
    
                File file = new File( fileName );
                ImageInputStream iis = ImageIO.createImageInputStream(file);
                Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
    
                if (readers.hasNext()) {
    
                    // pick the first available ImageReader
                    ImageReader reader = readers.next();
    
                    // attach source to the reader
                    reader.setInput(iis, true);
    
                    // read metadata of first image
                    IIOMetadata metadata = reader.getImageMetadata(0);
    
                    String[] names = metadata.getMetadataFormatNames();
                    int length = names.length;
                    for (int i = 0; i < length; i++) {
                        System.out.println( "Format name: " + names[ i ] );
                        displayMetadata(metadata.getAsTree(names[i]));
                    }
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    

    Please help :)

    • Muel
      Muel about 11 years
      How are you trying to run this programme? In Eclipse? How are you supplying the arguments to the programme? I'll edit my answer below based on this information.
    • Luckheart
      Luckheart about 11 years
      i run on java netbeans i didn't find filepath from that code :(
    • Muel
      Muel about 11 years
      You need to supply an absolute path to an image file for that code to work. Eg: C:\\Users\\luckheart\\Desktop\\image.png What is the file name (and location) of the image that you're trying to load?
    • Luckheart
      Luckheart about 11 years
      where i've to put ? C:\Users\luckheart\Pictures\Sample Pictures\Koala.jpg
  • Muel
    Muel about 11 years
    @Luckheart I've edited the answer to provide a simpler example. Once the simple example is working, try changing it to the previous example, and have a read of this: stackoverflow.com/questions/9168759/… to pass in external filenames in Netbeans.
  • Luckheart
    Luckheart about 11 years
    now how to read a set of image from the specified folder path ? i,m newbie in java :)
  • Mario Codes
    Mario Codes over 2 years
    This should be the accepted answer. 100% what I needed and code works out of the box.