Home > Digital Image Processing > Batch rename pictures of multiple recording devices to show date and time in filenames

Batch rename pictures of multiple recording devices to show date and time in filenames

Similar to sorting images into folders named after their date, we’re going to look at automatically renaming pictures – so that their names are based on timestamps they’ve been taken. This enables sorting pictures chronologically in pretty much all software that’s out there (as sorting alphabetically implies chronological sorting then). Note that the same is possible using exiftool only, but using a (from our point of view) slightly more complicated syntax (look e.g. here for renaming files after EXIF data, or here for updating EXIF data from filenames).

The problem

Imagine a group event with multiple people taking pictures using multiple cams. Usually, naming schemes of cameras are different, such as

IMG_1234.JPG
DCM_5678.jpg
...

If people later share images they could either put all into the same folder, or separate them by folders – we’re going to focus on the first case here. If these images get sorted alphabetically, they are not automatically sorted by their timestamps for the reason of using different naming schemes. On the one hand, for file explorers this can often be changed by sorting after image timestamps. On the other hand, this is not applicable for all cases: e.g. image viewers/galleries also need to feature sorting after timestamps for switching to the “next” picture. Panoramas created from multiple images also frequently do not contain timestamps any more, therefore sorting by timestamps causes panoramas to be on top/bottom of the list.

A uniform naming scheme that contain timestamps in names

For those reasons we tend to automatically rename all images to fit a uniform naming scheme such as

yyyy_mm_dd-hh_mm_ss_number_person.jpg

  • date and time are first in filenames – this automatically causes chronological sorting when sorting alphabetically (pretty much every program can sort files alphabetically)
  • number is the original sequential number of the image (contained in the new name to not lose any information)
  • person is an identifier of who and/or with which device the picture was taken

Automatically renaming pictures after their EXIF timestamp

At first we need to make sure that the EXIF timestamp DateTimeOriginal is set correctly for all images. In case all of these timestamps are shifted (typically, because the camera date and time were configured wrong) we can shift the corresponding EXIF entry using exiftool (adapt the offset):

exiftool -DateTimeOriginal+="00:00:00 00:00:00" -overwrite_original -ext FILENAMEEXTENSION -r DIRECTORY

As timestamps are correct we can rename images after their date and time taken:

old_fileending="JPG"                                   # original postfix of your files (file name extension)
old_praefix="IMG_"                                     # original prefix of your files
newname_postfix="_FsCam"                               # your new, personal name postfix
oldname_regex="s/$old_praefix//;s/.$old_fileending//"  # regex of how to modify the old filename before adding it to the new filename (e.g. replacing old pre- and postfix)
match_wildcards="$old_praefix*.$old_fileending"       # wildcards of which files process

for filepath_old in `find . -iname "$match_wildcards"`
do
    filename_old=`basename $filepath_old`
    filename_new=$(exiftool -S -DateTimeOriginal $filepath_old | awk 'BEGIN {FS=" "};{print $2" "$3}' | sed "s/:/_/g;s/ /-/g")_$(echo $filename_old | sed $oldname_regex)$newname_postfix.jpg
    rename -n -v "s/`echo $filename_old`/`echo $filename_new/`" $filepath_old
done
  • match_whitecards: defines which files you want to match
  • oldname_regex: defines how old filenames should be modified and preserved in new filenames
  • newname_postfix: identifier added to filenames (to identify person and device)

Finally, some words before starting to take pictures:

  • Ensure clock synchronization over all devices taking pictures (cameras, mobile phones, …) before starting – it just makes things easier. Otherwise you may experience “lag” effects (when looking through the pictures it seems like some person was a bit ahead or behind always). In case you already took pictures with multiple devices which experience lags: shift the EXIF image timestamps for specific devices as shown above.
  • If you want to sort videos too: take care of used time zones. Cameras usually encode the current device timestamps to the picture (the time shown on the device) – independent of the set time zone. In contrast, many mp4-recorders (like mobile phones) encode UTC timestamps instead of the time shown on the device. If you would use both types of timestamps without intermediate correction, “lags” might occur again.

Updating EXIF timestamps from filenames

In case you need to update timestamps after renaming images to the uniform naming scheme from above, e.g. for images not yet containing EXIF data at all (like panoramas) and/or in case of wrong naming (eventually caused by shifted EXIF timestamps) the following snippet could help.

# part 1: extract timestamp from filename and write it to EXIF
file_wildcard="*_FsCam.jpg"
for filepath in `find . -iname "$file_wildcard"`
do
  # extract timestamp from filename (it's the filename's prefix)
  # might look oldschool, but it's easy to adapt
  bname=$(basename $filepath)
  fdate=$(echo $bname | awk 'BEGIN {FS="-"};{print $1}')
  ftime=$(echo $bname | awk 'BEGIN {FS="-"};{print $2}')
  y=$(echo $fdate | awk 'BEGIN {FS="_"};{print $1}')
  m=$(echo $fdate | awk 'BEGIN {FS="_"};{print $2}')
  d=$(echo $fdate | awk 'BEGIN {FS="_"};{print $3}')
  h=$(echo $ftime | awk 'BEGIN {FS="_"};{print $1}')
  min=$(echo $ftime | awk 'BEGIN {FS="_"};{print $2}')
  s=$(echo $ftime | awk 'BEGIN {FS="_"};{print $3}')
  # write extracted timestamp to file as EXIF timestamp. first do a test run, then uncomment last line and run again
  echo "setting DateTimeOriginal" $y:$m:$d $h:$min:$s "for" $filepath
#   exiftool -DateTimeOriginal="$y:$m:$d $h:$min:$s" -overwrite_original $filepath
done

# part 2: shift EXIF timestamps (adapt offset)
for filepath in `find . -iname "$file_wildcard"`
do
    exiftool -DateTimeOriginal+="00:00:00 00:00:00" -overwrite_original $filepath
done

# part 3: replace the old name prefix timestamp with new (and now correct) one extracted from EXIF (first do test run, then remove -n from rename)
for filepath_old in `find . -iname "$file_wildcard"`
do
    filename_old=`basename $filepath_old`
    # remove the old prefix timestamp, keep other info
    filename_same=${filename_old:19:${#filename_old}}
    # create new filename from exif data and reainder of old filename
    filename_new=$(exiftool -S -DateTimeOriginal $filepath_old | awk 'BEGIN {FS=" "};{print $2" "$3}' | sed "s/:/_/g;s/ /-/g")$(echo $filename_same)
    rename -nv "s/`echo $filename_old`/`echo $filename_new`/" $filepath_old
done
  1. No comments yet.
  1. No trackbacks yet.

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 )

Google+ photo

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

Connecting to %s

%d bloggers like this: