public class ExifTool extends Object implements AutoCloseable
ExifToolBuilder
:
ExifTool tool = new ExifToolBuilder().build();
This mode assume that:
-Dexiftool.withPath=/usr/local/exiftool/bin/exiftool
).ExifTool
, you can also specify it during creation:
ExifTool tool = new ExifToolBuilder()
.withPath("/usr/local/exiftool/bin/exiftool")
.build();
Once created, usage is as simple as making calls to getImageMeta(File, Collection)
or
getImageMeta(File, Format, Collection)
with a list of Tag
you want to pull
values for from the given image.
In this default mode, calls to getImageMeta(java.io.File, java.util.Collection<com.thebuzzmedia.exiftool.Tag>)
will automatically
start an external ExifTool process to handle the request. After ExifTool has
parsed the tag values from the file, the external process exits and this
class parses the result before returning it to the caller.
Results from calls to getImageMeta(java.io.File, java.util.Collection<com.thebuzzmedia.exiftool.Tag>)
are returned in a Map
with the StandardTag
values as the keys and String
values for every
tag that had a value in the image file as the values. StandardTag
s with no
value found in the image are omitted from the result map.
While each StandardTag
provides a hint at which format the resulting value
for that tag is returned as from ExifTool (see Tag.parse(String)
), that
only applies to values returned with an output format of
StandardFormat.NUMERIC
and it is ultimately up to the caller to decide how
best to parse or convert the returned values.
The StandardTag
Enum provides the Tag.parse(String)
}
convenience method for parsing given `String` values according to
the Tag hint automatically for you if that is what you plan on doing,
otherwise feel free to handle the return values anyway you want.
-stay_open True/False
command line argument and in a busy system that is making thousands of calls
to ExifTool, can offer speed improvements of up to 60x (yes,
really that much).
This feature was added to ExifTool shortly after user
Christian Etter discovered the overhead
for starting up a new Perl interpreter each time ExifTool is loaded accounts for
roughly 98.4% of the total runtime.
Support for using ExifTool in daemon mode is enabled by explicitly calling
ExifToolBuilder.enableStayOpen()
method.
Calling this method will create an instance of ExifTool
with StayOpenStrategy
execution strategy.
Because this feature requires ExifTool 8.36 or later, this class will
actually verify support for the feature in the version of ExifTool
before successfully instantiating the class and will notify you via
an UnsupportedFeatureException
if the native
ExifTool doesn't support the requested feature.
In the event of an UnsupportedFeatureException
, the caller can either
upgrade the native ExifTool upgrade to the version required or simply avoid
using that feature to work around the exception.
stay_open
mode is used, there is the potential for
leaking both host OS processes (native exiftool
processes) as well as the
read/write streams used to communicate with it unless close()
is
called to clean them up when done. Fortunately, this library
provides an automatic cleanup mechanism that runs, by default, after 10 minutes
of inactivity to clean up those stray resources.
The inactivity period can be controlled by modifying the
exifTool.processCleanupDelay
system variable. A value of 0
or
less disabled the automatic cleanup process and requires you to cleanup
ExifTool instances on your own by calling close()
manually.
You can also set this delay manually using ExifToolBuilder
:
ExifTool exifTool = new ExifToolBuilder()
.enableStayOpen(60000) // Try to clean resources once per minutes.
.build();
Any class activity by way of calls to getImageMeta
will always
reset the inactivity timer, so in a busy system the cleanup thread could
potentially never run, leaving the original host ExifTool process running
forever (which is fine).
This design was chosen to help make using the class and not introducing
memory leaks and bugs into your code easier as well as making very inactive
instances of this class light weight while not in-use by cleaning up after
themselves.
The only overhead incurred when opening the process back up is a 250-500ms
lag while launching the VM interpreter again on the first call (depending on
host machine speed and load).
close()
on an instance of
this class, cleaning up the host process and read/write streams, the instance
of this class can still be safely used. Any followup calls to
getImageMeta
will simply re-instantiate all the required
resources necessary to service the call.
This can be handy behavior to be aware of when writing scheduled processing
jobs that may wake up every hour and process thousands of pictures then go
back to sleep. In order for the process to execute as fast as possible, you
would want to use ExifTool in daemon mode (use ExifToolBuilder.enableStayOpen()
)
and when done, instead of close()
-ing the instance of this class and throwing it
out, you can keep the reference around and re-use it again when the job executes again an hour later.
Pattern
s used to split the responses from the process are explicitly
compiled and reused, string concatenation is minimized, Tag name lookup is
done via a static final
Map
shared by all instances and
so on.
Additionally, extra care is taken to utilize the most optimal code paths when
initiating and using the external process, for example, the
ProcessBuilder.command(List)
method is used to avoid the copying of
array elements when ProcessBuilder.command(String...)
is used and
avoiding the (hidden) use of StringTokenizer
when
Runtime.exec(String)
is called.
All of this effort was done to ensure that imgscalr and its supporting
classes continue to provide best-of-breed performance and memory utilization
in long running/high performance environments (e.g. web applications).
stay_open
is disabled, then a one-shot process is used for each command.Modifier and Type | Method and Description |
---|---|
void |
close()
This method should be used to clean previous execution.
|
Map<Tag,String> |
getImageMeta(File image,
Collection<Tag> tags)
Parse image metadata.
|
Map<Tag,String> |
getImageMeta(File image,
Format format,
Collection<Tag> tags)
Parse image metadata.
|
Version |
getVersion()
Exiftool version pointed by this instance.
|
boolean |
isRunning()
This method is used to determine if there is currently a running
ExifTool process associated with this class.
|
void |
setImageMeta(File image,
Format format,
Map<Tag,String> tags)
Write image metadata in a specific format.
|
void |
setImageMeta(File image,
Map<Tag,String> tags)
Write image metadata.
|
public void close() throws Exception
ExifTool
from being re-used, it merely disposes of
the native and internal resources until the next call to
getImageMeta
causes them to be re-instantiated.close
in interface AutoCloseable
Exception
public boolean isRunning()
close()
and this class will automatically re-create them on the
next call to getImageMeta(java.io.File, java.util.Collection<com.thebuzzmedia.exiftool.Tag>)
if necessary.true
if there is an external ExifTool process is still
running otherwise returns false
.public Version getVersion()
public Map<Tag,String> getImageMeta(File image, Collection<Tag> tags) throws IOException
image
- Image.tags
- List of tags to extract.IOException
- If something bad happen during I/O operations.NullPointerException
- If one parameter is null.IllegalArgumentException
- If list of tag is empty.UnreadableFileException
- If image cannot be read.public Map<Tag,String> getImageMeta(File image, Format format, Collection<Tag> tags) throws IOException
image
- Image.format
- Output format.tags
- List of tags to extract.IOException
- If something bad happen during I/O operations.NullPointerException
- If one parameter is null.IllegalArgumentException
- If list of tag is empty.UnreadableFileException
- If image cannot be read.public void setImageMeta(File image, Map<Tag,String> tags) throws IOException
image
- Image.tags
- Tags to write.IOException
- If an error occurs during write operation.public void setImageMeta(File image, Format format, Map<Tag,String> tags) throws IOException
image
- Image.format
- Specified format.tags
- Tags to write.IOException
- If an error occurs during write operation.Copyright © 2016. All Rights Reserved.