3

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
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
user1311422
  • 85
  • 2
  • 2
  • 7
  • Really strange. It compiles fine? Maybe import it explicitly: `import com.drew.metadata.exif.GpsDescriptor;`. Maybe clean/rebuild project or so. Not sure what's happening; maybe some NetBeans magic with not including stuff on the classpath... – Torious Apr 15 '12 at 23:13
  • You genius. Importing the package explicitly has worked. Many many thanks! – user1311422 Apr 16 '12 at 13:41

1 Answers1

4

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.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Torious
  • 3,364
  • 17
  • 24
  • Thanks Torious. That's cleared things up a little. Using your code, I copied it into what I have but I'm getting one slight error. The error is in the second line of the code where it says metadata.get(GpsDirectory.class); – user1311422 Apr 15 '12 at 22:19
  • I should mention the error says "cannot find symbol" Symbol: method get(java.lang.Class) location: variable metadata of type com.drew.metadata.Metadata – user1311422 Apr 15 '12 at 22:22
  • Oh, it's supposed to say `metadata.getDirectory(...`, sorry about that. I edited it in the answer. – Torious Apr 15 '12 at 22:23
  • Exception in thread "main" java.lang.NoClassDefFoundError: metadata/GpsDescriptor at metadata.ExtractTags.getLatitude(ExtractTags.java:44) 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) Could this be due to the fact im calling it from another class. I have a main class which contains..... ExtractTags extractAllTags = new ExtractTags(); extractAllTags.getLatitude(); – user1311422 Apr 15 '12 at 22:34
  • You have to add the required package imports: `import com.drew.metadata.exif.*; import com.drew.metadata.iptc.*; import com.drew.metadata.jpeg.*;`. Consider using an IDE such as Eclipse, which will help with that sort of thing. If you still get more errors, edit your main post to include the code you have now. – Torious Apr 15 '12 at 22:38
  • Currently using NetBeans. Is Eclipse much better for debugging? I'm only using NetBeans so I can use the GUI builder. Still no luck with the program, same errors. Sorry to be a pain! – user1311422 Apr 15 '12 at 22:43
  • I've never used NetBeans myself, but Eclipse is great. Anyway, edit your main post to show your code, including your main class/method and the exact errors you get and indicate the lines. – Torious Apr 15 '12 at 22:46