Introduction
Tinkering with an image (JPG, TIFF, or even RAW) file's metadata (EXIF, IPTC, XMP, et. al.) is probably one of the not-so-common tasks a .NET developer has to mess around with, but on those occasions where it is needed, it is surprising to know that there are not a lot of options around. ImageMagick's .NET implementation isn't exactly updated (as far as I know), and there is no clear information on how to use it without having to see a shrink afterwards.
I have been faced with this challenge of programmatically updating image metadata, and the idea of using ImageMagick scared me. Fortunately, I have discovered a better way to do it using Microsoft's own free tools.
Please note that none of these are based on the documented .NET SDK supported by Microsoft. They could change this anytime they want, so be aware of this fact should you decide to use the code in a production environment.
Background
Microsoft has introduced this nifty tool to view/edit image metadata called the Pro Photo Tools 2.0. It's a freeware that is used to view update the EXIF/IPTC/XMP information of a wide range of image formats, including proprietary RAW formats from camera manufacturers. The tool comes with a number of DLLs that I will be using to view/update metadata in a C# application.
This requires the extensive use of the .NET Reflector and Visual Studio's debugger...and the usual screaming and cursing in front of the computer during the discovery process. ;-)
I have to be honest, this idea isn't exactly original. There has been a forum discussion somewhere on the intarwebs on using the DLLs bundled with the first version of Pro Photo Tools (called PhotoInfo). There has been a radical change with the way Microsoft deals with metadata from version 1.0 to 2.0, so I figured writing an article about it may be worthwhile.
Setting it Up
Download and install the Microsoft Pro Photo Tools 2.0 software and then fire up your Visual Studio 2008. Create a C# Console Application and reference Microsoft.ImageMetadata.dll from the %PROGRAMFILES%\Microsoft Pro Photo Tools directory. This DLL contains all the good stuff for reading and writing image metadata.
Dissecting the Pro Photo Tools DLLs
This requires a little bit of .NET Reflector ninja skills. Open Microsoft.ProPhotoToolsFoundation.dll and browse to the Resources folder, and save Microsoft.PhotoToolboxFoundation.ToolboxPolicy.xml to a local directory in your computer. We will make a reference to this file somewhere in the C# code that you will write.
The Code
Believe it or not, the hard part is done! Referencing the DLL. Now, you will just need to write this code in your test C# application:
try
{
var img_path = @"@C:\[PATH TO YOUR IMAGE FILE].jpg";
var p = (new MetadataPolicyManager()).loadPolicy(@"C:\[PATH TO POLICY FILE]" +
@"\Microsoft.PhotoToolboxFoundation.ToolboxPolicy.xml");
imgProxy = new ImageFileProxy(img_path, p);
object desc = imgProxy.Data[p.getTagIndex("Description")];
Console.WriteLine("Description: " + desc.ToString());
imgProxy.Data[p.getTagIndex("Description")] = "Description modified!";
imgProxy.commit();
}
catch (Exception ex)
{
}
img_path
is the path to the image file that you want to inspect/change the metadata of. And, remember the policy XML you extracted using .NET Reflector? You point loadPolicy()
to that location.
What Happened Here?
As you can see, not much is going on here when you run the application: you extracted the description from the image metadata and displayed it in the console screen. That's it!
That's it?
Yes, uneventful as it seems, that is all there is to it. That's the beauty of it: the simplicity! imgProxy
(ImageFileProxy
) pretty much takes the grunt work of loading the metadata into memory, and the imgProxy.Data
(an array) is the blob that contains all the image metadata. If you run the application through the debugger and inspect imgProxy
, you will see the rest of your image metadata! Not only that, the array contains objects that represent the data deserialized for you, not just some series of bytes that you need to format for display.
So What's with the Policy File?
Here is where the magic happens. I still haven't understood it fully, but suffice to say, it deals with all the "mappings" between the image metadata and the location of the metadata from within the header of the image file. You don't need to know the "location" of the metadata (regardless of whether its XMP, IPTC, or EXIF!), p.GetTagIndex()
does it for you! If you need to know the rest of the metadata keywords, all you need to do is take a peek of the policy XML file. Here are some of the keywords available:
- Description
- Keywords
- Copyright
- Rating
- SubjectReference
- Source
- Category
- CaptureDate
Updating the Metadata
As you might have noticed by now, imgProxy.Data
is read/write. To update the metadata, simply assign a new value or values, then call imgProxy.commit()
. Again, the simplicity is the major selling point here.
Anything Else?
Reading/updating the image metadata is one of the tricks that are offered by the Pro Photo Tools DLLs. As you inspect the DLL, there are also means to do GeoTagging, given your photo's Longitude and Latitude information in the header are present. Of course, that is beyond the scope of this article; I leave that to the adventurous .NET developer should he/she need those features in their .NET application.