Search code examples
javaimagemetadataexif

Can't seem to retrieve a ExifSubIFDDirectory


I'm trying to extract the Date info from a picture. I'm getting along quite good but I have this problem bugging me for 2 days. I've even rewriten the entire code once and still get it.

I obviously get an NP because I return a null in the method grabExifSubIFDDirectory. This is the main problem, it claims there is no Directory available while there should be one. Why can't it grab the directory? I'm using standrd jpegs and other formats.

The jar is placed inside a folder with pictures.

If somebody could point (hehe) me int the direction?

Package utils:

package utils;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JOptionPane;

public class FileUtils {

    private ArrayList<String> fileNamesList;

    public FileUtils(String jarFilePath) {
        setFileNames(jarFilePath);
    }

    // Retrieves a Metadata object from a File object and returns it.
    public Metadata grabFileMetaData(String filePath) {
        Metadata metadata = null;
        File file = new File(filePath);
        try {
            metadata = ImageMetadataReader.readMetadata(file);
        } catch (ImageProcessingException e) {
            JOptionPane.showMessageDialog(null, "Error: " + e);
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Error: " + e);
        }
        return metadata;
    }

    // Retrieves a ExifSubIFDDirectory object from a Metadata object and returns it. 
    public ExifSubIFDDirectory grabExifSubIFDDirectory(Metadata metadata, String filePath) {
        ExifSubIFDDirectory directory;
        if (metadata.containsDirectory(ExifSubIFDDirectory.class)) {
            directory = (ExifSubIFDDirectory) metadata.getDirectory(ExifSubIFDDirectory.class);
            return directory;
        } else {
            JOptionPane.showMessageDialog(null, "File at: " + filePath + " does not contain exif date.");
            return null;
        }
    }

    // Retrieves a Date object from a ExifSubIFDDirectory object and returns it.
    public Date grabDate(ExifSubIFDDirectory directory) {
        Date date;
        date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
        return date;
    }

    // Return the actual Date object using the above methods.
    public Date getDate(String filePath) {
        return grabDate(grabExifSubIFDDirectory(grabFileMetaData(filePath), filePath));
    }

    // Retrieves the names of the files in the same folder as the executed jar.
    // Saves them in a variable.
    public void setFileNames(String jarPath) {
        ArrayList<String> temp = new ArrayList();
        String path = jarPath;
        String files;
        File folder = new File(path);
        File[] listOfFiles = folder.listFiles();
        for (File listOfFile : listOfFiles) {
            if (listOfFile.isFile()) {
                files = listOfFile.getName();
                if (!"PhotoRenamer.jar".equals(files) && !"Thumbs.db".equals(files)) {
                    temp.add(files);
                }
            }
        }
        this.fileNamesList = temp;
    }

    // getter
    public ArrayList<String> getFileNamesList() {
        return fileNamesList;
    }

}

Package domein:

package domein;

    import utils.FileUtils;
    import utils.JarUtils;
    import java.util.ArrayList;

    public class DomeinController {

        FileUtils fileUtils;
        JarUtils jarUtils;

        public DomeinController() {
            this.jarUtils = new JarUtils();
            this.fileUtils = new FileUtils(jarUtils.getJarPath());
        }

        public ArrayList<String> getFileNamesList() {
            return fileUtils.getFileNamesList();
        }

        public String getJarPath() {
            return jarUtils.getJarPath();
        }

        // Retrieve string from Date object of the file with the number i.
        public String getDate(int i) {
            return fileUtils.getDate(createFilePath(i)).toString();
        }

        public String createFilePath(int i) {
            return getJarPath() + "\\" + fileUtils.getFileNamesList().get(i);
        }

    }

Package startup:

 package startup;

import domein.DomeinController;
import java.net.URISyntaxException;
import javax.swing.JOptionPane;

public class Main {

    public static void main(String[] args) throws URISyntaxException {
        DomeinController  dc = new DomeinController();

        // print out jar path
        JOptionPane.showMessageDialog(null,dc.getJarPath());

        // print out file names in folder
        String lijstje = "";
        for (int i=0;i<dc.getFileNamesList().size();i++){
            lijstje += dc.getFileNamesList().get(i);
        }
        JOptionPane.showMessageDialog(null,lijstje);

        JOptionPane.showMessageDialog(null,dc.getDate(1));
    }

}

Solution

  • The getDate(String filePath) method is working just fine, I tested it.

    So it must come from the picture itself

    • Test your code with a single picture (with a unit test), make sure the getDate method is working for you. Do the test with a picture coming from the Internet too.
    • As Metadata is not null, the file does exist so the picture has no EXIF information, there is no possible doubt.
    • Use this tool to check if your pictures have EXIF information