Batch EXIF Tagging?
August 18, 2005 2:34 PM   Subscribe

Is there an EXIF wiz in the house?

I have a large number of photos that have their "date taken" in the filename (YYMMDD-##.jpg, to be exact), but they have no EXIF info. Before I upload them to flickr, I'd like to change that. Since it's a lot of pictures, I'm looking for a way to automate the process (plus it's a matter of principle, since the information is already digital I shouldn't have to do it by hand.)

I know about EXIFer, but it doesn't seem to have this kind of batch function. Is there any other program that will let me batch-process these files and add EXIF information taken from the filename? I know there are taggers that do this kind of thing for mp3s, so why not for EXIF? Thankyoumuch.
posted by muckster to Computers & Internet (19 answers total) 1 user marked this as a favorite
 
I wrote this little Perl script for doing exactly what you're doing, but I had a data file that contained a tab delimited list with the filename, title, and caption. This script ate up the data, wrote the IPTC values to the jpgs and saved them to out/

use Image::IPTCInfo;
use strict;

foreach my $line (<>) {
my ($jpg, $title, $caption) = split(/\t/, $line);
my $info = new Image::IPTCInfo($jpg);
if (defined($info)) {
$info->AddKeyword('some keyword');
$info->SetAttribute('province/state', "");
$info->SetAttribute('city', "San Francisco");
$info->SetAttribute('country/primary location name', "");
$info->SetAttribute('category', "some category");
$info->SetAttribute('object name', $title);
$info->SetAttribute('headline', $title);
$info->SetAttribute('by-line title', $title);
$info->SetAttribute('caption/abstract', $caption);
$info->SetAttribute('copyright notice', "");
$info->SaveAs("out/$jpg");

print "Saving $jpg...\n";
}
}

On preview, I forget not everyone's a programmer; I was assuming that parsing the filename for the date could be an exercise left for the reader. Let me know if that isn't the case.
posted by Loser at 2:55 PM on August 18, 2005


Response by poster: Wow. No, sorry, I'm not a programmer (unless you count BASIC...) so I wouldn't even know where to begin. I'm on Windows XP but could upload everything to a UNIX server where I can run perl scripts, in case that makes any difference.

If you had the patience to explain to me how to use this, that'd be fantastic.
posted by muckster at 3:07 PM on August 18, 2005


Um, none of the 26298292 results from googling 'batch exif' will do this? Like this or this or this?

The last one is postcardware and it's possible if you write the dude he'd add this feature.
posted by phearlez at 3:09 PM on August 18, 2005


Response by poster: phearlez, I know there are shareware programs that may or may not do what I need. I know that Exifer (your third link) won't. I was hoping somebody could tell me before I have to install a dozen different programs.

That's why I was asking.
posted by muckster at 3:23 PM on August 18, 2005


I've used jhead to change the date on a large number of files. It's a command line utility available on a number of platforms.

You'd use it something like this:

C:\My Pictures\Fascinating Vacation Photos>jhead.exe -ts2005:08:18-23:25:29 *

But there are plenty of other things you can do with it. Read the usage page or run jhead -h
posted by cactus at 4:25 PM on August 18, 2005


Response by poster: That looks promising, cactus. The thing I haven't figured out yet is how to insert the info from the file name instead of specifying a date after -ts. Looks like &i inserts the filename, but that's in the format YYMMDD, so -ts &i probably won't work. There's an &o but I don't know what it stands for.
posted by muckster at 4:35 PM on August 18, 2005


I'm sure imatch (photool.com) can do this. The trial version lasts for 30 days. It's really meant for cataloging, so you'd be using a tiny fraction of it's power, but I'm sure it allows for generating EXIF data from filenames. It's $60 after 30 days.
posted by Jack Karaoke at 5:15 PM on August 18, 2005


Er... photools.com (previous link is correct, just not my text)
posted by Jack Karaoke at 5:16 PM on August 18, 2005


Response by poster: I'll try that, Jack. Thank you.
posted by muckster at 5:28 PM on August 18, 2005


EXIFutils will do everything you want and more. There is decent enough documentation on how to use it.
posted by daveirl at 12:47 AM on August 19, 2005


Response by poster: Thanks for the answers, but so far, I can't figure out how to do it with either iMatch or EXIFutils.
posted by muckster at 9:28 AM on August 19, 2005


If Loser would like to flesh out his perl script to parse the filenames for the input I will be glad to run it through my Activestate perl compiler to get you a windows executable...
posted by phearlez at 11:02 AM on August 19, 2005


My curiosity got the better of me. Here's a WAY quick implementation, intolerant of even the slightest variation on YYMMDD-#.jpg, tho # can be any number of digits, 1 to 2829438929292.

Writes the newly tagged into a subdir named 'tagged'. Only does this operation on files in its own directory.

If you run it more than once you need to delete that tagged dir first - the ExifTool module won't overwrite a file.

The below script is compiled into a windows executable you can download here.

use Image::ExifTool 'ImageInfo';
use strict;
$|=1;

opendir(DIR, ".") or die "can't opendir current directory: $!";
my $info = new Image::ExifTool;
opendir(destDIR, "./tagged") or mkdir("./tagged");
while (defined(my $file = readdir(DIR))) {
if ($file !~ /(\d\d)(\d\d)(\d\d)-\d+.jpg/) {
print "Skipping $file: doesn't meet YYMMDD-#.jpg requirement\n";
} else {
print "Tagging $file with date 20$1:$2:$3 00:00:00 in directory tagged\n";
$info->SetNewValue("DateTimeOriginal", "20$1:$2:$3 00:00:00");
$info->WriteInfo($file, "tagged/$file");
print "wrote retagged-$file\n";
}
}
closedir(DIR);
posted by phearlez at 12:54 PM on August 19, 2005


Response by poster: Whoa, that's fantastic. Let me try that.

Oh--looks like I'll have to tweak this for files from 99? That's how far it goes back. Didn't expect to run into a Y2K problem at this late date. Let me try it on a folder that doesn't have 1999 pix in it first...
posted by muckster at 1:38 PM on August 19, 2005


Response by poster: phearlez, I get this:

Skipping 020306-01.JPG: doesn't meet YYMMDD-#.jpg requirement

etc.

Is it the capital .JPG that's the problem? It's only capitalized in DOS, looks lowercase in Windows Explorer.
posted by muckster at 1:49 PM on August 19, 2005


Response by poster: OK, I tried renaming on to .jpg under DOS, and now I get:

Tagging 020406-1.jpg with date 2002:04:06 00:00:00 in directory tagged
Error while attempting to call Image::ExifTool::SetNewValue
Can't locate Image/ExifTool/Writer.pl in @INC (@INC contains:) at (eval 14) line
1.

Is ExifTool something I need to have installed? Thank you so much for this; looks like it's almost working.
posted by muckster at 1:52 PM on August 19, 2005


Best answer: Hmmm looks like I don't know how to use that executable builder as well as I thought. Amazing given the 2 times I've done it before :)

Okay! Now years under 30 are 20XX, years 30+ are 19XX and the search for filename works on both .jpg and .JPG (and even .JpG etc you crazy kids!). The executable is updated, you can find it above.

For those who are interested the new code is:
use Image::ExifTool 'ImageInfo';
use strict;
$|=1;

opendir(DIR, ".") or die "can't opendir current directory: $!";
my $info = new Image::ExifTool;
opendir(destDIR, "./tagged") or mkdir("./tagged");
while (defined(my $file = readdir(DIR))) {
    if ($file !~ /(\d\d)(\d\d)(\d\d)-\d+.jpg/i) {
      print "Skipping $file: doesn't meet YYMMDD-#.jpg requirement\n";
    } else {
      if ( $1 < 30 ) {br>
        print "Tagging $file with date 20$1:$2:$3 00:00:00 in directory tagged\n";
      $info->SetNewValue("DateTimeOriginal", "20$1:$2:$3 00:00:00");
      } else {
        print "Tagging $file with date 19$1:$2:$3 00:00:00 in directory tagged\n";
      $info->SetNewValue("DateTimeOriginal", "19$1:$2:$3 00:00:00");
      }
      $info->WriteInfo($file, "tagged/$file");
      print "wrote retagged-$file\n";
  }
  }
closedir(DIR);
And yeah, it's stinky. Sue me - I was trying to spend the least amount of time possible on it.
posted by phearlez at 3:09 PM on August 19, 2005


You know, it occurs to me I remember reading about some jerk getting a software patent for dealing with Y2K issues though the above simple "<3 0=2000,>30 1900" method. If I get sued over this I'm sending you the bill, muckster!
posted by phearlez at 3:12 PM on August 19, 2005


Response by poster: COMPLETELY FREAKIN' AWESOME! phearlez, you RULE! We're talking about something like 30,000 photos here, and all I have to do now is drop this .exe file in there and let it do its thing. I'm blown away. It's working like a charm. This couldn't be easier. Thanks a TON!
posted by muckster at 3:47 PM on August 19, 2005


« Older Looking for a bigger TFT   |   How can I get a video game made? Newer »
This thread is closed to new comments.