J-Exiftool: read and write Exif tags in Java

A while ago I started looking for a Java library which allowed me to read Exif-tags. It quickly turned out that the best implementations relied on the Perl executable ExifTool  by Phil Harvey and a quick look at the documentation told me why: it’s super awesome, it’s super reliable and after many years of development it’s still being updated ! However, this could not be said off the Java libraries which use Exiftool: none of them support writing Exif-tags and only a few are still being developed.

This is where J-ExifTool comes in: it’ll be the first Java-library which allows you to read and write Exif-tags by using the ExifTool  by Phil Harvey. The read functionality is already working pretty okay tough a lot of details are still missing (like formatting and casting the results).

Some of the goals of J-ExifTool are:

  • Java 7
  • High performance for processing batches of images
  • Easy to use
  • Open-Source
  • Well documented and correct code (IntelliJ Code inspection + FindBugs + Checkstyle)
  • A s***-load of logging

If everything is working correctly, reading an Exif-tags using J-ExifTool should be as simple as:

System.setProperty(ExecutionConstant.EXIFTOOLPATH, "lib\\exiftool.exe");
JExifTool tool = new JExifTool();
JExifInfo info = tool.getInfo(new File("D:\\Users\\pw999\\Documents\\Development\\Bitbucket\\j-exiftool\\lib\\DSC00216.JPG"));
String iso = info.get(Tag.ISO);
System.out.println(iso);

Update: if simplified, as suggested by Phil Harvey, the usage of the API. What I’ve started was oriented too much towards batch-processing (internally it still is, but you can’t use it anymore).
What’s left is more easy and straigtforward to use.

Advertisement

14 thoughts on “J-Exiftool: read and write Exif tags in Java

  1. Sounds good! Just a couple of questions/comments:

    1) Since “High performance” is a goal, I wanted to be sure you were aware of the exiftool -stay_open feature.

    2) ExifTool tag names may have dashes in them. Is this a problem for the “Tag.ISO” syntax?

    3) The “simple” Java code above still looks complicated to me. I’m just thinking out loud here, but could this be simplified to something more like this?:

    JExifTool tool = new JExifTool(“lib\\exiftool.exe”);
    JExifToolInfo info = tool.extractInfo(new File(“D:\\Users\\pw999\\Documents\\DSC00216.JPG”));
    String iso = info.getValue(“ISO”);
    System.out.println(iso);

    This corresponds roughly to how things are done in the ExifTool Perl API.

    1. 1) yes I do 🙂
      2) Tag is just an Enum which contains the command line argument and expected data type.
      3) It’s indeed a bit complex, I’m maybe thinking a bit too much in the direction of processing large batches of images.
      Thanks for the input, I’m definately going to use it in some way.

  2. This is a very useful and amazing lib. But I cann’t find a way to modify a photo’s shooting time, or a photo which have no shooting time and i wanna to add a shooting time in it.
    Could you give an example code? and Thank you very much! for your reply or email me:”dontpostyourmail”@gmail.com

    1. Hey coolcooldool,

      normally, the shooting time is save in the DateTimeOriginal tag (be.pw.jexif.enums.tag.ExifIFD.DATETIMEORIGINAL).
      This is a simple example I copied from my unit tests:

      String date = DateUtil.fromDate(new Date());
      JExifInfo info = tool.getInfo(write01);
      String result = info.setTagValue(ExifIFD.DATETIMEORIGINAL, date);
      
  3. I’m really glad I found this tool. I was looking at having to implement my own api for modifying exif data in java and I was getting nowhere quickly. I had a couple questions though.
    1. I have is there any way to disable logging or provide my own log4j file? We use file appenders for all our output and I don’t want to be dumping a lot of data to the console. For debug purposes I can see all the debug being very useful but otherwise I’d like to silence most of it unless something goes wrong.
    2. Is there any plan to support a classpath variable for something like EXIFTOOL_HOME=/lib/exiftool rather than having to set the system property at runtime?

    1. 1) Hey, you should be able to override the log configuration by either having your log4j.properties first in the classpath or by using -Dlog4j.configuration=PATH_TO_FILE.
      2) That is possible, never thought of it. If you file a request in bitbucket then I’ll certainly have a look at it.

  4. Hello again,

    I saw the update in v8 for the classpath. Thanks for that! However I started running into an issue locally when I try to run it. My output is saying

    15:25:26,063 INFO [be.pw.jexif.JExifTool] (Thread-13 (HornetQ-client-global-threads-112893766)) Starting ExifTool
    15:25:26,067 INFO [be.pw.jexif.JExifTool] (Thread-13 (HornetQ-client-global-threads-112893766)) ExifTool was started
    15:25:26,161 ERROR [be.pw.jexif.internal.thread.event.DebugHandler] (Thread-127) Error opening arg file “/apps/JMS Instance/bin/args”

    After that any operations I attempt to perform result in a deadlock exception and it exiting out. Was wondering if you’d seen anything like this before and if you might have any suggestions?

    1. Hmmm, that is an error from exiftool itself. it’s either because there are spaces in the path or because it can not access the files because it doesn’t exist. But I think it’ll be the first one. Can you try running it on a path without spaces?

    2. Billy,

      I did some tests and it’s indeed cause by the space in the path. I’ve tried escaping the spaces, quoting the path, quoting using single quotes but it still keeps failing. Surprisingly enough, if I call exiftool directly from the command line with spaces in the args-path (quoted of course), then it works. But I can’t get the same result from j-exiftool.

      As a workaround, I’ve added the “args.path” system property so you can manually override the path to one without spaces (so something like -Dargs.path=/tmp/args should work find). I also added a pseudo-random suffix to the args file-name, might come in handy in multi-threaded environments 😉

      Anyway, you can download 0.0.8.1 here https://bitbucket.org/P_W999/j-exiftool/downloads/j-exiftool-0.0.8.1.jar

  5. Hi Phillip,
    Thanks for providing this tool. I have to delete all exif data from image and save that image to other location.

    Can you provide me some code snippet for this.

    Thanks.

  6. Hi Phil Harvey,

    Need to Write a custom XMP-paf property file using EXIF tool from java code. can you share the details of how to pass the EXIF_Config file along with file to the executor class. If you have already implemented such code, can you share it with me ?

    Regards,
    Praveen Dhandapani

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s