10

I have a collection of photos that have no date information. They have no Exif data, and the file modification dates are all identical. The only sequence is in the file name: image-0001.jpg, image-0002.jpg, etc.

Now I want to assign a date to these files (preferably in Exif) that are all 10 seconds apart. I'm not so interested in what exactly the base date and time will be, just that they all increment 10 seconds. So the first image will get 0:00:00, the second 0:00:10, the third 0:00:20, etc.

Is this possible with ExifTool, or other Windows applications? We're talking about several thousands of images, so doing this manually is out of the question ;-)

MikeW
  • 33,408
  • 10
  • 88
  • 123
Peter
  • 459
  • 3
  • 9

4 Answers4

11

There's already a similar question on the ExifTool forums. It can be done using two sequential ExifTool commands. First, make sure all the date to the same

exiftool -datetimeoriginal='2015:02:22 00:00:00' DIR

And then increment the time on each

exiftool '-datetimeoriginal+<0:0:${filesequence}0' DIR

This command creates backup files. Add -overwrite_original to suppress the creation of backup files. Add -r to recurse into subdirectories. If this command is run under Windows CMD, change the single quotes into double quotes.

Many of the other answers here involve looping and running exiftool once/twice per file. This is Exiftool Common Mistake #3. Exiftool's biggest performance hit is the startup time. When processing thousands of images, this will greatly increase the processing time.

StarGeek
  • 3,803
  • 11
  • 21
  • Hi StarGeek. How is this answer different from junkyardsparkle's one? – Saaru Lindestøkke Feb 22 '15 at 17:59
  • @Bart, here, $filesequence is a magic exiftool variable; in junkyardsparkle's, $file is a bash variable. This is more portable; the other ties the time to the filename rather than to the order exiftool happens to read them. – mattdm Feb 22 '15 at 18:36
  • Neat. I had a feeling exiftool could do something like that, but if it's in the docs, then I missed it. – junkyardsparkle Feb 22 '15 at 20:03
  • I can't get this to work. I'm using exiftool "-datetimeoriginal+<0:0:$filesequence" image-0010.jpg (in DOS format), but result is "0 image files updated, 1 image files unchanged" – Peter Feb 22 '15 at 21:42
  • Can this command be modified if I would want 3 seconds between each photo? – Peter Feb 22 '15 at 21:42
  • @Peter Your test isn't working because $filesequence starts at 0. When you have only one file, it's only ever set to 0, which makes the whole thing a no-op. It should work if you have a whole directory of files. – mattdm Feb 22 '15 at 22:15
  • 2
    Also note that in bash ' vs " is significant — with double quotes, the $ will be caught and interpreted by the shell (as in Jens' answer), but in this answer it needs to be a single quote so it's interpreted by ExifTool internally. – mattdm Feb 22 '15 at 22:16
  • 3
    NOTE: You should also use "-fileorder FileName" in the increment command, otherwise the files may not actually be read in the expected order. – junkyardsparkle Feb 22 '15 at 23:45
  • @Peter, To change it to 3 second intervals is possible, but a bit more complex. You would have to use

    -datetimeoriginal+<0:0:${filesequence;$_*=3}

    (braces required). At that point you're starting to use the advanced formatting and slipping some perl code in there.

    – StarGeek Feb 23 '15 at 07:35
  • One more thing to add is that if you run these commands on a directory (useless to run on single files as @mattdm pointed out), this will be much faster as ExifTool is invoked only once for each command. Any looping will have to invoke it for each file and the startup each time will be a big performance hit. – StarGeek Feb 23 '15 at 07:42
  • 1
    Ah, I was under the impression that $filesequence extracted the number from the filename, but it is actually looking at the directory sort order. Also, in Microsoft Windows command prompt, we have to use " instead of '. But now it works perfect! – Peter Feb 24 '15 at 14:04
6

Since the best answers use non-Windows syntax, I will here post their code converted for Microsoft Windows.

@StarGeek solution, very fast and simple:

First set a base timestamp to all images:

exiftool -datetimeoriginal="2015:01:01 12:00:00" DIR

(DIR is the name of the folder containing all images.)

Then assign incremental timestamps:

exiftool "-datetimeoriginal+<0:0:${filesequence;$_*=3}" DIR

(In this case 3 is the number of seconds you want between each photo.)

Note the use of double quotes, this is required on Windows systems.


@junkyardsparkle solution, which was initially the only one I was able to work with:

This requires creating a batch file, because of the commands involved.

@echo off
setlocal EnableDelayedExpansion
for %%f in (*.jpg) do (
    echo %%f
    rem Get filename
    set n=%%f
    rem Extract number
    set n=!n:~6,4!
    rem Interpret as decimal
    set /a n=1!n!-10000
    rem Convert to seconds
    set /a n = n*10
    rem Assign base timestamp
    exiftool -DateTimeOriginal="2000:1:1 00:00:00" %%f
    rem Assign time increment
    exiftool -DateTimeOriginal+="00:00:!n!" %%f
)
Peter
  • 459
  • 3
  • 9
4

Try Irfanview. It is freeware (AFAIR) and has a very flexible batch renaming system.

Other than that I would try writing a script, something along the lines of

for X in $(seq -w 0 20) ; do
  plus=$(expr $X \* 10)
  exiftool -alldates+="0:0:0 0:0:$plus" image_$X.jpg
done

The first line creates a loop through the numbers in the file names that you have, eg. 00..20. If you have 1000 images, the command would be seq -w 0 1000. The option -w adds leading zeros to the numbers.

The second line defines the increment - 10 in this case. Without units so far.

The format string in the third line "0:0:0 0:0:$plus" defines what the variable $plus means, in this case seconds. If you wanted minutes you'd write 0:0:0 0:$plus:0. The format is "year:month:day hour:minute:second". So here, we have a 10 second increment.

This is a batch done in 'bash' (Linux shell), you might have to adapt it to Windows or use a Linux live system to do the conversion.

Note that all files should have an (identical) Exif tag (DateTimeOriginal) before this can be used, since it increments the existing tags only. But you can simply write a tag with one exiftool command.

I tested this with 20 example files and the tags were correctly written.

Jens
  • 141
  • 3
  • Interesting that exiftool works with > 59 in the seconds field; cool. Other than that, and being a little shorter and cleaner, this is basically the same as my approach, except mine parses the index from the filename and yours generates the filenames from the index. In practical application, half a dozen of one and six of the other, I think. :) – mattdm Feb 20 '15 at 21:59
  • Thanks, and very true. When I started figuring this out there weren't any answers, so you were faster. :) – Jens Feb 20 '15 at 22:31
3

Well, I didn't post my bash answer because the question specifically asked about a Windows solution, but since two other people did, here's what I came up with:

for file in *.jpg
do
  exiftool -DateTimeOriginal="1111:11:11 00:00:00" $file
  exiftool -DateTimeOriginal+="00:00:${file:6:4}0" $file
done

Avoids messing with the date command. :)

Note that in the part where it says ${file:6:4}, the "6" represents the point in the filename where the sequence number starts, and the "4" represents the length of that sequence. If your files exactly match the "image-0001.jpg, image-0002.jpg" given in the question, this will work as is; otherwise, adjust to match.

mattdm
  • 143,140
  • 52
  • 417
  • 741
junkyardsparkle
  • 5,404
  • 16
  • 29
  • That is way cooler than my solution. But it can still be a little optimized :) by calling the first exiftool only once on all files at once and looping only through the second command. (Right?) – Jens Feb 20 '15 at 22:56
  • Yeah, that would be more efficient. :P Anyway, your answer is much better pseudocode for anyone actually trying to port it to DOS or whatnot. I can't seem to avoid evil bashisms to save my life. – junkyardsparkle Feb 20 '15 at 23:26
  • 2
    "evil bashims" is a tautology. :p But thanks. I actually started with a Ruby script but then I realized this would be total overkill. – Jens Feb 22 '15 at 09:33
  • Fantastic! I've used your example to write a batch file. Since I can't write code blocks in comments, I will write my own answer. – Peter Feb 22 '15 at 21:55
  • @Peter I'm not sure this really deserves to be the accepted answer, though... assuming the method presented by StarGeek actually works (I haven't tested it) it's really the best, most portable solution. – junkyardsparkle Feb 22 '15 at 23:20