Metadata Extraction - Java

user1311422 picture user1311422 · Apr 15, 2012 · Viewed 9k times · Source

I'm trying to create a program that extracts the metadata from an image file. So far, I've managed to create a program that prints out all the metadata, but I can't figure out how to specify the program to print out only certain things (File name, latitude, longitude, date accessed). I've been trying to get my head around it for the past four hours. Here is the code I have so far.....

Main Class:

package metadata;
import com.drew.metadata.exif.*; 
import com.drew.metadata.iptc.*; 
import com.drew.metadata.jpeg.*;
public class MetaData {

    public static void main(String[] args) {

        ExtractTags extractAllTags = new ExtractTags();

        //extractAllTags.getTags();
        System.out.println("\n\n\n Has this ");
        extractAllTags.getLatitude();     
    }
}

Second Class:

package metadata;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.GpsDirectory;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.drew.metadata.exif.*; 
import com.drew.metadata.iptc.*; 
import com.drew.metadata.jpeg.*;

public class ExtractTags {

    String allTags;
    String latitude;
    File jpegFile = new File("C:\\Users\\Public\\Pictures\\Sample Pictures\\HTC Desire.jpg");

    public String getTags() {

        try {
            Metadata metadata = ImageMetadataReader.readMetadata(jpegFile);

            for (Directory directory : metadata.getDirectories()) {
                for (Tag allTags : directory.getTags()) {

                    System.out.println(allTags);
                }
            }
        } catch (ImageProcessingException ex) {
            Logger.getLogger(MetaData.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(MetaData.class.getName()).log(Level.SEVERE, null, ex);
        }
        return allTags;
    }

    public String getLatitude() {
        try {
            Metadata metadata = ImageMetadataReader.readMetadata(jpegFile);
            if (metadata.containsDirectory(GpsDirectory.class)) {
                GpsDirectory gpsDir = (GpsDirectory) metadata.getDirectory(GpsDirectory.class);
                GpsDescriptor gpsDesc = new GpsDescriptor(gpsDir);
                System.out.println("Latitude: " + gpsDesc.getGpsLatitudeDescription());
            }
        } catch (ImageProcessingException ex) {
            Logger.getLogger(ExtractTags.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Error 1");
        } catch (IOException ex) {
            Logger.getLogger(ExtractTags.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Error 2");
        }

        return latitude;
    }
}

Errors:

Exception in thread "main" java.lang.NoClassDefFoundError: metadata/GpsDescriptor
    at metadata.ExtractTags.getLatitude(ExtractTags.java:47)
    at metadata.MetaData.main(MetaData.java:13)
Caused by: java.lang.ClassNotFoundException: metadata.GpsDescriptor
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    ... 2 more

Answer

Torious picture Torious · Apr 15, 2012

You can get the Directory subclass of your choice by using Metadata.getDirectory(Class). Each type of Directory has an associated Descriptor you can use to interpret the raw data of the Directory.

For example, latitude can be obtained from the GpsDirectory using a GpsDescriptor like this:

GpsDirectory gpsDir = (GpsDirectory) metadata.getFirstDirectoryOfType(GpsDirectory.class);

if (gpsDir != null) {
    GpsDescriptor gpsDesc = new GpsDescriptor(gpsDir);
    System.out.println("Latitude: " + gpsDesc.getGpsLatitudeDescription());
}

See the documentation for the specific type of Descriptor you are using to see the methods it provides to get the data you want.