Sorting images by EXIF date
Introduction
At least once a year we go for holiday together with some friends. No question, they all bring their digital cameras and take a load of pictures.
Right after we get back home they send me their images to upload them to our gallery.
The Problem
Then i usually end up with a directory structure looking smthg like:
. ├── philipp │ └── S8000 │ ├── DSC_0700.JPG │ ├── DSC_0701.JPG │ └── DSC_0709.JPG ├── iris │ ├── C5600 │ │ ├── DSCN4664.JPG │ │ ├── DSCN4666.JPG │ │ └── DSCN4667.JPG │ └── D80 │ ├── DSC_0830.JPG │ ├── DSC_0837.JPG │ ├── DSC_0838.JPG │ └── DSC_0839.JPG ├── nina │ └── S3000 │ ├── DSCN4610.JPG │ ├── DSCN4616.JPG │ └── DSCN4617.JPG └── tom ├── D70 │ ├── DSC_4040.JPG │ ├── DSC_4048.JPG │ └── DSC_4049.JPG └── iphone ├── IMG_0104.JPG └── IMG_0105.JPG
First of all, there might be duplicate filenames as in the example above. But the major problem is that these photos are not sorted by the date they’d been taken which makes it hard to just browse them all and sort out the ones we dislike.
The Script
This is far from being perfect. Actually it’s just a quick hack, but it does the job for me.
It sorts all images given according to its EXIF CreateDate
, copies/moves the files and prefixes them with an incrementing number.
Prerequisites:
- Image::Exiftool
#!/usr/bin/perl -w ################################################## #Move or copy images and rename them to be sorted by EXIF-CreateDate #cmdline options: #./cmd -move <list of images> #./cmd -copy -dest <destination directory> <list of images> ################################################## use strict; use Image::ExifTool; use Time::Local; use Getopt::Long; use File::Basename; use File::Copy; our $dest; our $copy; our $move; my %Info; GetOptions ('dest=s' => \$dest, 'copy' => \$copy, 'move' => \$move ); foreach (@ARGV) { GetDateAndTime($_, \%Info); } SortAndMove(\%Info); sub GetDateAndTime { my ($srcfile, $Info_ref) = @_; my $srcfileExif = new Image::ExifTool; my $info = $srcfileExif->ImageInfo($srcfile,"CreateDate"); $$info{'CreateDate'} =~ s/\s+/:/g; my ($year,$mon,$mday,$hour,$min,$sec) = split(/:/, $$info{'CreateDate'}); $mon = $mon-1; $$Info_ref{$srcfile} = timelocal($sec,$min,$hour,$mday,$mon,$year); } sub SortAndMove { my ($Info_ref) = @_; my $count = sprintf("%0".length(keys %$Info_ref)."d",0); foreach (sort {$$Info_ref{$a} cmp $$Info_ref{$b}} keys %$Info_ref) { move("$_",dirname($_) . "/" . $count . "_" . basename($_)) if $move; copy("$_",$dest . "/" . $count . "_" . basename($_)) if $copy; $count++; } } |
Tested on:
- ArchLinux
- Debian GNU/Linux Squeeze
Cameras tested with:
- Nikon D70s
- Nikon D80
- Nikon Coolpix 5600
- Apple Iphone 3GS
Example 1: Sort on Copy
Input Filenames: $ find a/ -xdev -iname "*.jpg*"
a/iris/D80/DSC_0838.JPG a/iris/C5600/DSCN4665.JPG a/philipp/S8000/DSC_0700.JPG a/philipp/S8000/DSC_0705.JPG a/nina/S3000/DSCN4613.JPG a/nina/S3000/DSCN4614.JPG a/tom/iphone/IMG_0102.JPG a/tom/D70/DSC_4043.JPG a/tom/D70/DSC_4048.JPG
Copy and sort:
$ NameByExifDate.pl -c -d b/ `find a/ -xdev -iname "*jpg*"`
Resulting Filenames: $ find b/ -xdev -iname "*.jpg*"
b/0_DSC_0700.JPG b/1_DSCN4613.JPG b/2_DSCN4614.JPG b/3_DSC_0705.JPG b/4_IMG_0102.JPG b/5_DSCN4665.JPG b/6_DSC_0838.JPG b/7_DSC_4043.JPG b/8_DSC_4048.JPG
Example 2: Sort on Move
Input Filenames: $ find a/ -xdev -iname "*.jpg*"
a/iris/D80/DSC_0838.JPG a/iris/C5600/DSCN4665.JPG a/philipp/S8000/DSC_0700.JPG a/philipp/S8000/DSC_0705.JPG a/nina/S3000/DSCN4613.JPG a/nina/S3000/DSCN4614.JPG a/tom/iphone/IMG_0102.JPG a/tom/D70/DSC_4043.JPG a/tom/D70/DSC_4048.JPG
Move and sort:
$ NameByExifDate.pl -m `find a/ -xdev -iname "*jpg*"`
Resulting Filenames: $ find a/ -xdev -iname "*.jpg*"
a/iris/D80/6_DSC_0838.JPG a/iris/C5600/5_DSCN4665.JPG a/philipp/S8000/0_DSC_0700.JPG a/philipp/S8000/3_DSC_0705.JPG a/nina/S3000/1_DSCN4613.JPG a/nina/S3000/2_DSCN4614.JPG a/tom/iphone/4_IMG_0102.JPG a/tom/D70/7_DSC_4043.JPG a/tom/D70/8_DSC_4048.JPG
The sort on move routine preserves the original directory structure while the sort on copy routine flattens the hierarchy to a single destination directory.
I highly appreciate feedback of any kind.
andi
15 March, 2011 - 10:35
exiv2 rename *
is doing the same!!!tom
15 March, 2011 - 11:08
ohhh….damn. knowing this would have saved me 30min of work.
thank you for the information, andi.