August 2, 2009

Command-line Photo Processing

My girlfriend, and I recently took a trip to California, which was fantastic. We went backpacking in Yosemite for a week, and then spent another week in San Francisco and Napa Valley. During this time, we took a little over 1400 photos on our two digital cameras. When we came back, I sat down to figure out how to consolidate our pictures so that they would display chronologically. Although it took me a while to research all the different programs for this, I ended up discovering just a handful of commands that reduced the task from a several-day monotonous chore to a several-minute fire-and-forget job.

The starting point:

  • She used a Canon PowerShot SD1100 IS, which saves files like this: IMG_1700.JPG.
  • I used an OLYMPUS E-500, which saves files like this: AB276025.ORF for raw and like this: AB276025.JPG.

Here is a list of the programs I used:

  • dcraw
  • ImageMagick
  • exiv2
  • jhead

Here is a summary of the commands I issued:

dcraw *.ORF
mogrify -format jpg *.ppm
exiv2 insert -S.ORF *.jpg
jhead -n%Y.%m.%d-%H.%M.%S-e *
jhead -model E-500 -n%Y.%m.%d-%H.%M.%S-j *

I did not include the command to adjust the timestamps of my photos here because I corrected my camera’s clock, and that step will no longer be necessary. Plus, it’s confusing for other people who just want to run these commands to see what happens.

And here is the process:

Since I took about 200 raw photos, my first task was to convert them into jpegs.

dcraw *.ORF
mogrify -format jpg *.ppm

Dcraw is used to develop” raw formatted files into an intermediate format, ppm. In my experience, dcraw does a fine job choosing the correct metrics to develop the pictures, but it also has a whole host of options for changing color, white balance, etc. Mogrify is part of the ImageMagick suite. Specifically, it is used to modify files in-place (the other programs in the ImageMagick suite create a new file each time you run them), but it has one handy feature that allows you to batch-convert files from one format to another. Ppm-to-jpeg is just one of these options. Now, because this conversion does not preserve the metadata, which I would need later, I used this command to insert the data from the raw files into the jpegs:

exiv2 insert -S.ORF *.jpg

One thing to know about this command is that exiv2 is designed to work with Canon raw format (CRW). When applied to others, it makes a guess about which raw metadata fields map to which jpeg Exiv fields without promising to get it absolutely right. That said, it worked just fine with Olympus raw (ORF) for me.

NOTE: this command inserts into every jpg the information from the ORF file with the corresponding name. Therefore, you must do this step before renaming the jpegs.

Once I had all my photos in jpeg format, I decided to rename them by date and time so that my girlfriend’s and my photos would both be part of a single timeline. I also put an e’ at the end of her pictures and a j’ at the end of mine. Jhead is the perfect program for this:

jhead -n%Y.%m.%d-%H.%M.%S-e *
jhead -model E-500 -n%Y.%m.%d-%H.%M.%S-j *

The first command renames each file based on the date taken” field. This command allows you to specify your own format for the date and time information, so I used my standard year.month.day-(24)hour.minute.second. The documentation for Jhead details how to use these tokens. The first command also renames all the files to end with e’. The second command uses the -model argument to rename only my pictures so that they end in j’. The -model argument can be used to limit most other commands to pictures from a specific camera. This feature was important for the last step.

When the pictures were all renamed according to when they were taken, I noticed that my pictures were slightly out of sync with my girlfriend’s. Since I did not have the cameras handy to compare their times, I just looked for a pair of pictures, one from each of our cameras, that captured a unique moment. I used the time difference in the photos’ timestamps to calculate that my camera was about 15 minutes and 20 seconds ahead of my girlfriend’s. Then I issued this command to correct it:

jhead -model E-500 -ta-0:15:20 *.jpg

The -model argument limits this command to my camera, and -ta can be used to adjust the time taken by a specified amount, positive or negative–negative, in this case. One more of these to rename my pictures based on their new timestamps, and I was done!

jhead -model E-500 -n%Y.%m.%d-%H.%M.%S-j *

Next time, I might roll all these commands into a script, but I also like seeing the changes to the files after each step. Each of the programs I discussed here have a large number of options, so you can use them to do much more than I accomplished here.


cli photography


Next post
Efficient Command-Line Accounting with Ledger and Account-CLI Inspired by Andrew Cantino’s blog about accounting with Ledger and Reckon, I started this year out following his workflow. I’ve used MS MyMoney,