Exifacto – a Nicer EXIF Library for .NET

I’ve been looking at reading and parsing EXIF data for a project I’m working on; the project itself is still a long way off, but – as is so often the case in software - the EXIF code I’m working on is starting to show some real promise, so I’ve cleaned up the (very basic!) implementation I’ve currently got and put it up on Google Code for the world to play with.

The System.Drawing classes in .NET expose EXIF data as key/value pairs, but it’s about as unfriendly an API as I’ve ever seen. Each EXIF tag is exposed as a numeric ID (which is one of about a hundred magic numbers defined in the EXIF spec), and an array of bytes – it’s up to you to work out which item is which, extract, parse and decode the byte arrays, and make sense of the result. Just to make things interesting, most numeric data in EXIF is stored as ratios – pairs of signed or unsigned ints representing the numerator/denominator of a rational number. Which makes perfect sense if you’re a photographer - always talking in F-stops and hundredths of a second and fractions of an inch – but makes things just a bit harder if you’re trying to get this stuff out into your .NET application.

For example - to get the date a photograph was taken, using .NET code, you need to do this:

DateTime myImageTaken = DateTime.MinValue;

Bitmap bitmap = new Bitmap(@"image001.jpg");
foreach(PropertyItem item in bitmap.PropertyItems) {
   if (item.Id == 0x9003) {
       string exifDate = Encoding.ASCII.GetString(item.Value);
       if (DateTime.TryParseExact(exifDate,
           exifDateFormats,
           CultureInfo.InvariantCulture,
           DateTimeStyles.AllowInnerWhite,
           out myImageTaken)
       ) {
           break;
       }
   }
}
Console.WriteLine("Image taken at: " + myImageTaken.ToString());

exifactoWith Exifacto, you do this:

ExifData exifData = new ExifData(“image001.jpg”);
Console.WriteLine(“Image taken at: “ + exifData.DateTimePhotoCreated)

Right now, it’s got support for the basic string and DateTime information, and a couple of the lookup properties wrapped in .NET enumerations; next thing is parsing and arithmetic for signed and unsigned rational numbers. The actual implementation isn’t really the point, though - the idea is to get as much descriptive documentation into the Intellisense comments as possible, ending up with a discoverable API that takes a lot of the confusion out of working with EXIF data.

It’s being hosted at http://code.google.com/p/exifacto/ – Subversion only for now, but source code & DLLs to follow once I’ve tied up a few loose ends.