Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Cheatsheet for image / video metadata manipulation.

Cheatsheet for image / video metadata manipulation.

Last updated 2019-07-24

Disclaimer

until more specific license...

THE CONTENT BELOW IS PROVIDED "AS-IS",
WE DISCLAIM LIABILITY FOR ALL USES TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW.
WE MAKE NO GUARANTEES.

In other words, don't be dumb, backup your data and don't blame us for losing your precious data.

Important options

-h  ➔  the most important of all, this cheatsheet is not exhaustive.
-s  ➔  use tag names instead of description, good for scripting since you want to use [-tagname] options.
-G  ➔  add group names to each tag, good if you deal with both Exif, XMP, etc.
-P  ➔  preserve [FileModifyDate], useful if you do not have any timestamp info in the file.

Examples

$ exiftool -s -G IMG_123.JPG
[show all metadata]

$ exiftool -AllDates IMG_123.JPG
Date/Time Original              : 2018:09:14 08:53:41
Create Date                     : 2018:09:14 08:53:41
Modify Date                     : 2018:09:14 08:53:41

$ exiftool -AllDates -s IMG_123.JPG
DateTimeOriginal                : 2018:09:14 08:53:41
CreateDate                      : 2018:09:14 08:53:41
ModifyDate                      : 2018:09:14 08:53:41

$ exiftool -DateTimeOriginal -s IMG_123.JPG
DateTimeOriginal                : 2018:09:14 08:53:41

$ exiftool -exif:DateTimeOriginal -G -s IMG_123.JPG
[EXIF]          DateTimeOriginal                : 2018:09:14 08:53:41

$ exiftool -xmp:DateTimeOriginal -G -s IMG_123.JPG
[nothing to see]

Reading metadata

Checking timestamps

exiftool -time:all -s .
exiftool -AllDates -s .

Searching for Files

This is often made more simple with conditions. If you need more advanced comparisons, learn Perl.

Find files with a jpg or jpeg extension

-ext jpg -ext jpeg

Find files without a DateTimeOriginal

-if '(not $datetimeoriginal)'

Or more specifically in a particular group

-if '(not ${exif:datetimeoriginal})'

Example

$ exiftool -s -G -filename -if '(${exif:datetimeoriginal})'  -ext jpg IMG_*
======== IMG_123.JPG
[File]          FileName                        : IMG_123.JPG
======== IMG_2131.jpg
[File]          FileName                        : IMG_2131.jpg
    2 image files read

Find files invalid DateTimeOriginal

Often enough, my battery is dead, and I put new ones in, but I forget to set the time on the camera.

-if '$DateTimeOriginal lt "2013:05:01 00:00:00"'

Find files that aren't named properly

I like to use ISO date in the filename.

-if '$filename !~ /^\d/'

Output photos that don't have datetimeoriginal to a CSV

Note this can take a long time if you have a lot of jpgs

# You'll need to set your Dropbox folder path. I have mine set as a global variable
OLDFILE="$DROPBOX_PERSONAL/nodates.csv"

FILECOUNT=$(mdfind -count -onlyin "$DROPBOX_PERSONAL" 'kMDItemKind =="JPEG image"')
while IFS= read -r -d '' n; do
    FILECOUNT=$(( $FILECOUNT - 1 ))
    if grep -q "$n" "$OLDFILE"; then
        echo "Skipping $n"
        continue
    fi

    echo -ne "Remaining: $FILECOUNT\r"
    exiftool -q -if '(not $datetimeoriginal or ($datetimeoriginal eq "0000:00:00 00:00:00"))' -csv -common "$n" | sed 1d >> "$DROPBOX_PERSONAL/nodates.csv"
done < <( mdfind -onlyin "$DROPBOX_PERSONAL" 'kMDItemKind =="JPEG image"' -0 )

See files File Modify Date recursively in a directory who don't have datetimeoriginal set

exiftool -filemodifydate -r -if '(not $datetimeoriginal or ($datetimeoriginal eq "0000:00:00 00:00:00")) and ($filetype eq "JPEG")' .

Modifying Files

Create Captions From a Filename

The command alone will put the full filename in the comments. If you want to add the filename without the extension, add the example exiftool config file found here

# This is the command if you have the config installed
exiftool '-Comment<BaseName' '-UserComment<BaseName' .

# Getting the filename without the config file, but with a for-loop
for i in *; do 
	FileName="${i%%.*}"
	exiftool "-Comment=$FileName" "-UserComment=$FileName" "$i";
done

Change JPG to jpg and MOV to mov in filenames

Learn more about -filename and -directory on the exiftool docs.

exiftool '-filename=%f.%le' -ext jpg -ext mov *

example, using -testname instead to play pretend.

$ exiftool '-testname=%f.%le' IMG_*
'IMG_123.JPG' --> 'IMG_123.jpg'
Warning: File name is unchanged - IMG_2131.jpg
Warning: File name is unchanged - IMG_2132.jpeg
    0 image files updated
    3 image files unchanged

Change last created and modified for files in a directory

The date syntax has to be YYYY:MM:DD HH:MM:SS

Option 1:

find . -name "*.jpg" | while read filename;  
    exiftool "-AllDates=1986:11:05 12:00:00" "$filename";
done

Option 2:

exiftool "-AllDates=1986:11:05 12:00:00" -if '$filetype eq "JPEG"' .

Timeshift Photos by One Year

Info at Time Shift

exiftool "-AllDates+=1:0:0 0" .

Fix timestamps

Because exiftool copies files before renaming them to overwrite your files, you want to get this part right. Otherwise you may end up processing GBs of data multiple times.

exiftool \
    -overwrite_original \
    -if '$createdate lt "2013:05:01 00:00:00"' \
    '-quicktime:createdate+=1:0:16 11:40:0' \
    '-QuickTime:ModifyDate<$createdate' \
    '-QuickTime:TrackCreateDate<$createdate' \
    '-QuickTime:TrackModifyDate<$createdate' \
    '-QuickTime:MediaCreateDate<$createdate' \
    '-QuickTime:MediaModifyDate<$createdate' \
    -ext mp4 \
    .


exiftool \
    -overwrite_original \
    -if '$DateTimeOriginal lt "2013:05:01 00:00:00"' \
    '-exif:DateTimeOriginal+=1:0:16 11:40:0' \
    '-AllDates+=1:0:16 11:40:0' \
    -ext jpg \
    .

Rename files to datestamp

Filename looks like 2014-01-01 12:00:00.jpg and will append -NUM if DateTimeOriginal is the same for multiple files

exiftool '-FileName<DateTimeOriginal' -d "%Y-%m-%d %H.%M.%S%%-c.%%e" .  

Examples

exiftool \
    '-filename<${DateTimeOriginal}%.3c.jpg' \
    -d %y%m%d_%H%M%S \
    -if '$datetimeoriginal' \
    -ext jpg -ext jpeg \
    .

exiftool \
    '-filename<${DateTimeOriginal}_somelabel_%.3c.jpg' \
    -d %y%m%d_%H%M%S \
    -if '$datetimeoriginal' \
    -ext jpg -ext jpeg \
    .

for quicktime videos (see quicktime ref)

exiftool \
    '-filename<${quicktime:createdate}%.3c%.le' \
    -d %y%m%d_%H%M%S \
    -if '${quicktime:createdate}' \
    -ext mov -ext avi -ext mp4 \
    .

Rename Files to With Milliseconds

Good for burst photos where the seconds are all the same. If milliseconds are only out to 2 digits, use ${SubSecCreateDate} instead

Found at this forum post.

exiftool -v '-Filename<${datetimeoriginal}${subsectimeoriginal;$_.=0 x(3-length)}.%e' -d %Y%m%d_%H%M%S .

Update any photo that doesn't have DateTimeOriginal to have it based on file modify date

exiftool \
    '-datetimeoriginal<filemodifydate' \
    -if '(not $datetimeoriginal or ($datetimeoriginal eq "0000:00:00 00:00:00")) and ($filetype eq "JPEG")' \
    .

Set DateTimeOriginal to Any Arbitrary Timestamp

exiftool '-datetimeoriginal=2015:01:18 12:00:00' .

Moving/Copying Files

Copy directory recursively into organized folder

exiftool \
    -o ~/dummy/ \
    -if '$filesize# > 300000' \        
    '-Directory<CreateDate' \
    -d "~/Desktop/old_photos2/%Y/%m %B" \
    -r "~/Desktop/iPhoto Library/"
  • -o ~/dummy This flag is to copy, not move. The directory is a fallback if the flag isn't available on the given photo. Good if using something like DateTimeOriginal

  • -if '$filesize# > 300000' gets files that are over 300kB. I was parsing an iPhoto library where there were thumbnails. The # turns the value to a number. you can use the flag -n to turn all values to numbers

  • '-Directory<CreateDate' Create directories based on the CreateDate of the photos

  • -d "~/Desktop/old_photos/%Y/%m %B" Create folders with the given date format.

  • -r Run recursively

Geotagging

To tag all my ULM pictures with coordinates -21.152441, 55.279274.

exiftool \
    -exif:gpslatituderef=-1 \
    -exif:gpslatitude=-21.152441 \
    -exif:gpslongituderef=1 \
    -exif:gpslongitude=55.279274 \
    *ULM*

Create KML from geotagged photos

DESKTOP=$HOME/Desktop
cat $DESKTOP/kml-start.fmt > out.kml
exiftool -n -r -q -p $DESKTOP/kml-placemark.fmt . >> out.kml
cat $DESKTOP/kml-end.fmt >> out.kml

Create CSV of Geo Information

exiftool -csv -filename -imagesize -gps:GPSLatitude -gps:GPSLongitude ./ > long.csv

References

Update Notes

  • 2019-07-24 - added more commands for searching for files, fix title formatting, geotagging example
  • 2017-03-18 - added command to create comments from a filename
  • 2015-08-11 - added line to rename files based on milliseconds
  • 2015-01-18 - added line on how to set a date for a particular photo(s)
  • 2014-12-26 - Adding new recursive command to rename JPG to jpg. Info on using sh with -exec here
  • 2014-12-25 - Added line for copying photos into organized photos.
@dnozay

This comment has been minimized.

Copy link
Owner Author

@dnozay dnozay commented Jul 24, 2019

@dnozay

This comment has been minimized.

Copy link
Owner Author

@dnozay dnozay commented Jul 24, 2019

http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=8359.0

exiftool -if '$ShutterCount' '-FileName<${ShutterCount; $_ = substr("000000$_",-6);}.%e' -r DIR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment