Try it yourself: All of these examples are using the images provided in the tests directory in the source
Understanding input and output from PyExifTool base methodsAlmost all methods in PyExifTool revolve around the usage of two methods from the base exiftool.ExifTool
class.
It is important to understand the ouput from each of these commands, so here’s a quick summary (you can click through to the API to read more details)
Input parametersBoth methods take an argument list *args
. Examples:
Note
As a general rule of thumb, if there is an unquoted space on the command line to exiftool, it’s a separate argument to the method in PyExifTool.
If you have a working exiftool command-line but having trouble figuring out how to properly separate the arguments, please refer to the FAQ
Calling directly:
exiftool command-line:
exiftool -XMPToolKit -Subject rose.jpgPyExifTool:
execute("-XMPToolKit", "-Subject", "rose.jpg")
Using argument unpacking of a list:
exiftool command-line:
exiftool -P -DateTimeOriginal="2021:01:02 03:04:05" -MakerNotes= "spaces in filename.jpg"PyExifTool:
Note
Parameters which need to be quoted on the command line generally do not need to be quoted in the parameters to PyExifTool. In fact, quoting may have unintended behavior.
In this example, DateTimeOriginal value is not quoted in the parameter to execute().
execute(*["-P", "-DateTimeOriginal=2021:01:02 03:04:05", "-MakerNotes=", "spaces in filename.jpg"])
Getting JSON output using argument unpacking of a list:
exiftool command-line:
exiftool -j -XMP:all -JFIF:JFIFVersion /path/somefile.jpgPyExifTool:
execute_json(*["-XMP:all", "-JFIF:JFIFVersion", "/path/somefile.jpg"])
exiftool.ExifTool.execute_json()
Returns a
list
ofdict
Each
dict
is a result from a fileEach
dict
contains a key “SourceFile” which points to the relative or absolute file path of fileAll other keys/value pairs are requested metadata
Returns a
str
Typically used for setting tags as no values are returned in that case.
Using methods provided by exiftool.ExifToolHelper
:
ExifToolHelper provides some of the most commonly used operations most people use exiftool for
Getting TagsGet all tags on a single file
from exiftool import ExifToolHelper with ExifToolHelper() as et: for d in et.get_metadata("rose.jpg"): for k, v in d.items(): print(f"Dict: {k} = {v}")Dict: SourceFile = rose.jpg Dict: ExifTool:ExifToolVersion = 12.37 Dict: File:FileName = rose.jpg Dict: File:Directory = . Dict: File:FileSize = 4949 Dict: File:FileModifyDate = 2022:03:03 17:47:11-08:00 Dict: File:FileAccessDate = 2022:03:27 08:28:16-07:00 Dict: File:FileCreateDate = 2022:03:03 17:47:11-08:00 Dict: File:FilePermissions = 100666 Dict: File:FileType = JPEG Dict: File:FileTypeExtension = JPG Dict: File:MIMEType = image/jpeg Dict: File:ImageWidth = 70 Dict: File:ImageHeight = 46 Dict: File:EncodingProcess = 0 Dict: File:BitsPerSample = 8 Dict: File:ColorComponents = 3 Dict: File:YCbCrSubSampling = 2 2 Dict: JFIF:JFIFVersion = 1 1 Dict: JFIF:ResolutionUnit = 1 Dict: JFIF:XResolution = 72 Dict: JFIF:YResolution = 72 Dict: XMP:XMPToolkit = Image::ExifTool 8.85 Dict: XMP:Subject = Röschen Dict: Composite:ImageSize = 70 46 Dict: Composite:Megapixels = 0.00322
Get some tags in multiple files
from exiftool import ExifToolHelper with ExifToolHelper() as et: for d in et.get_tags(["rose.jpg", "skyblue.png"], tags=["FileSize", "ImageSize"]): for k, v in d.items(): print(f"Dict: {k} = {v}")Dict: SourceFile = rose.jpg Dict: File:FileSize = 4949 Dict: Composite:ImageSize = 70 46 Dict: SourceFile = skyblue.png Dict: File:FileSize = 206 Dict: Composite:ImageSize = 64 64
Setting date and time of some files to current time, overwriting file, but preserving original mod date
from exiftool import ExifToolHelper from datetime import datetime with ExifToolHelper() as et: now = datetime.strftime(datetime.now(), "%Y:%m:%d %H:%M:%S") et.set_tags( ["rose.jpg", "skyblue.png"], tags={"DateTimeOriginal": now}, params=["-P", "-overwrite_original"] )(No output is returned if successful)
Setting keywords for a file.
from exiftool import ExifToolHelper with ExifToolHelper() as et: et.set_tags( ["rose.jpg", "skyblue.png"], tags={"Keywords": ["sunny", "nice day", "cool", "awesome"]} )(No output is returned if successful)
By default, ExifToolHelper has some built-in error checking, making the methods safer to use than calling the base methods directly.
Warning
While “safer”, the error checking isn’t fool-proof. There are a lot of cases where exiftool just silently ignores bad input and doesn’t indicate an error.
Example using get_tags() on a list which includes a non-existent file
ExifToolHelper with error-checking, using
exiftool.ExifToolHelper.get_tags()
from exiftool import ExifToolHelper with ExifToolHelper() as et: print(et.get_tags( ["rose.jpg", "skyblue.png", "non-existent file.tif"], tags=["FileSize"] ))Output:
Traceback (most recent call last): File "T:\example.py", line 7, in <module> et.get_tags(["rose.jpg", "skyblue.png", "non-existent file.tif"], tags=["FileSize"]) File "T:\pyexiftool\exiftool\helper.py", line 353, in get_tags ret = self.execute_json(*exec_params) File "T:\pyexiftool\exiftool\exiftool.py", line 1030, in execute_json result = self.execute("-j", *params) # stdout File "T:\pyexiftool\exiftool\helper.py", line 119, in execute raise ExifToolExecuteError(self._last_status, self._last_stdout, self._last_stderr, params) exiftool.exceptions.ExifToolExecuteError: execute returned a non-zero exit status: 1ExifTool only, without error checking, using
exiftool.ExifTool.execute_json()
(Note how the missing file is silently ignored and doesn’t show up in returned list.)from exiftool import ExifToolHelper with ExifToolHelper() as et: print(et.get_tags( ["rose.jpg", "skyblue.png", "non-existent file.tif"], tags=["FileSize"] ))Output:
[{'SourceFile': 'rose.jpg', 'File:FileSize': 4949}, {'SourceFile': 'skyblue.png', 'File:FileSize': 206}]
Example using exiftool.ExifToolHelper.get_tags()
with a typo. Let’s say you wanted to get_tags()
, but accidentally copy/pasted something and left a =
character behind (deletes tag rather than getting!)…
Using
exiftool.ExifToolHelper.get_tags()
from exiftool import ExifToolHelper with ExifToolHelper() as et: print(et.get_tags(["skyblue.png"], tags=["XMP:Subject=hi"]))Output:
Traceback (most recent call last): File "T:\example.py", line 7, in <module> print(et.get_tags(["skyblue.png"], tags=["XMP:Subject=hi"])) File "T:\pyexiftool\exiftool\helper.py", line 341, in get_tags self.__class__._check_tag_list(final_tags) File "T:\pyexiftool\exiftool\helper.py", line 574, in _check_tag_list raise ExifToolTagNameError(t) exiftool.exceptions.ExifToolTagNameError: Invalid Tag Name found: "XMP:Subject=hi"Using
exiftool.ExifTool.execute_json()
. It still raises an exception, but more cryptic and difficult to debugfrom exiftool import ExifTool with ExifTool() as et: print(et.execute_json(*["-XMP:Subject=hi"] + ["skyblue.png"]))Output:
Traceback (most recent call last): File "T:\example.py", line 7, in <module> print(et.execute_json(*["-XMP:Subject=hi"] + ["skyblue.png"])) File "T:\pyexiftool\exiftool\exiftool.py", line 1052, in execute_json raise ExifToolOutputEmptyError(self._last_status, self._last_stdout, self._last_stderr, params) exiftool.exceptions.ExifToolOutputEmptyError: execute_json expected output on stdout but got noneUsing
exiftool.ExifTool.execute()
. No errors, but you have now written to the file instead of reading from it!from exiftool import ExifTool with ExifTool() as et: print(et.execute(*["-XMP:Subject=hi"] + ["skyblue.png"]))Output:
Using methods provided by exiftool.ExifTool
Calling execute() or execute_json() provides raw functionality for advanced use cases. Use with care!
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4