Java wrapper for ExifTool

Started by halloleo, August 19, 2011, 04:29:48 AM

Previous topic - Next topic

halloleo

Hi there

What is a good java wrapper for ExifTool? I know about im4java and MOSS, but which one is the best? Has anyone experience?

Many thanks, Leo

rkalla

Hey Leo,

I haven't used either of those integrations, but did just release a brand new Java integration with a very strong focus on usability with a robust underlying design.

I provided some example code in this thread, you can check the project page for more information about the history of the project, its design, usage, examples, performance, source code and downloads.

It is all released under the commercial friendly Apache 2 license and all code is accessible on GitHub.

If you are a "cut to the chase!" kind of developers, dive into the Javadoc here, there is copious amounts of documentation on the overarching design and usage of the class.

Really all you need to know is:

ExifTool tool = new ExifTool();
Map<Tag, String> resultMap = tool.getImageMeta(myImageFile, Tag... tags)


"tags" is just a varargs param, so you can pass 1 or more (or an array) of the tags you want out of an image. If you just want to see some quick-output, just pass "Tag.values()" which searches for all supported tags in your image and will give them back to you.

If you are interested in using the new -stay_open True functionality ("daemon mode") for performance reasons, just pass "Feature.STAY_OPEN" to the constructor.

Then you can call close() yourself OR let the automatic background thread cleanup the host process and read/write streams for you after a specified (default is 10mins) interval of inactivity. You can still re-use the instance though after it cleans up, the resources are just re-created.

Bottom line is that the class is designed to be robust yet easy to use. You can ignore all those details and just use it and it will "do the right thing".

Sorry I can't speak to the other two implementations you asked about, I just haven't used them.

gwegner

Sounds interesting. Is your wrapper as well able to perform tasks like extracting JPG previews from RAW files:

-if $jpgfromraw -b -overwrite_original -jpgfromraw -w \"" + jpgname + "\" -execute -if $previewimage -b -overwrite_original -previewimage -w \"" + jpgname +"\";

and extract XMP from DNG ?

-b -xmp -w! .xmp -ext DNG -r \"" + rawname + "\"";

it would be especially usefull to get the output as stream...

Looking forward to hear from you!

rkalla

gwegner,

Currently the implementation doesn't allow that. I had to start first with the simplest/most common use-cases which was extrating meta from images.

As the tool's popularity has grown more requests have come in for more advanced features (writing meta, extracting thumbnails, etc.) and these are all things I'm prioritizing and looking into.

Some require re-engineering of certain code paths to account for (all for the better, just more flexible).

If you wouldn't mind, filing an issue for the project:
https://github.com/thebuzzmedia/exiftool

with details of how you would want the behavior to behave is helpful, especially when I am addressing a feature or func of ExifTool that I have not encountered before and may not be familiar with.

Thanks!

gwegner

Thank you for your quick answer. I'm using native Java libraries for most of the XMP related stuff because of the performace - currently I'm only using Exiftool to extract previews and get XMP from DNG and I'm trying to figure out the fastest way possible to accomplish these tasks and I thought you might have already had some ideas.
I think I'm going to try to figure it out by myself in the first instance. Currently I work with intermediate JPG files written by ExifTool but I think it should be possible to read the jpg data directy via InputStream.

gwegner

I tried the whole evening to find a way to extract a preview with ExifTool directly to a BufferedImage in Java - unfortunately without success.

This is what I did:

// proc = new ProcessBuilder( System.getProperty( "user.dir" )
                      + File.separator + "exiftool.exe", "-stay_open", "True", "-@", "-" ).start();
        launchExifTool(); // basically only initializes  a new OutputStreamWriter( proc.getOutputStream );

        String t = "-b" + "\n"
                + "-overwrite_original" + "\n"
                + "-jpgfromraw" + "\n"
                + "C:\\temp\\test.nef" + "\n"
                + "-execute" + "\n";

        try {
            writer.write( t );
            writer.flush();

            String s = null;
           
            ImageIO.read( proc.getInputStream() );  // this is where it never returns. ***
           
            while( (s = reader.readLine()) != null ) {
                System.out.println( s );
                if( s.equals( "{ready}" ) ) {
                    break;
                }
            }
           
            writer.write( "-stay_open\nFalse\n");
        } catch( IOException ioe ) {
            ioe.printStackTrace();
        }


*** I'm not sure what happens there, it might be due to the fact that the stream ends with {ready} that the ImageIO Method hangs, I don't know how to check for the end of the stream to pass only the jpg to ImageIO.read()

Is there any java guru out there that could help me onto the right path?
Any help would be really apreciated!

Thank you in advance,
Gunther

Phil Harvey

Hi Gunther,

Can't you just read the stream yourself unto memory and keep reading until the stream ends with "{ready}\n", then remove the "{ready}\n" and you've got the PreviewImage in memory so you can do whatever you want with it.

PreviewImages are small enough to buffer in memory (a few MB at most).

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

halloleo

Quote from: rkalla on August 22, 2011, 12:10:11 AM
I haven't used either of those integrations, but did just release a brand new Java integration with a very strong focus on usability with a robust underlying design.

I provided some example code in this thread, you can check the project page for more information about the history of the project, its design, usage, examples, performance, source code and downloads.
...

Thanks rkalla, I'll give it a try.

Cheers, Leo