Click here to Skip to main content
15,868,419 members
Articles / Programming Languages / C#

Reading and Writing Photo Metadata Programmatically Using Microsoft Pro Photo Tools

Rate me:
Please Sign up or sign in to vote.
4.81/5 (11 votes)
24 Oct 2009CPOL4 min read 122.2K   42   41
A way to update photo metadata (EXIF, XMP, IPTC, etc.) using the DLLs used by Microsoft Pro Photo Tools.

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.

Reflector01.GIF

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:

C#
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) 
{
  // write exception handler 
}

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I have dabbling with Microsoft Technologies far longer than I want to admit. Smile | :) My main area of expertise is in the field of integration and most of them are implemented using Microsoft BizTalk.

When I'm not busy with my day job I can usually be seen in front of my Playstation or out somewhere with my camera. Wink | ;-)

Comments and Discussions

 
GeneralRe: Only works on your computer Pin
Dexter Legaspi7-Jan-10 4:38
Dexter Legaspi7-Jan-10 4:38 
GeneralRe: Only works on your computer Pin
Steini kallinn19-Jan-10 21:55
Steini kallinn19-Jan-10 21:55 
GeneralCould not load file or assembly 'Microsoft.ImageMetadata, Version=2.2.912.3, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format. Pin
RJMaly1-Dec-09 6:03
RJMaly1-Dec-09 6:03 
GeneralDecoding the metadata Pin
rctaubert29-Oct-09 3:01
rctaubert29-Oct-09 3:01 
GeneralRe: Decoding the metadata Pin
Dexter Legaspi29-Oct-09 5:21
Dexter Legaspi29-Oct-09 5:21 
GeneralRe: Decoding the metadata Pin
rctaubert29-Oct-09 6:13
rctaubert29-Oct-09 6:13 
I'm glad you didn't read mine first.

As I stated, we are heavily into Genealogy. We love sharing family pictures. I tried several 'Picture Managers' but none were suitable for sharing. I came across MS Photo Tools Pro and really liked the idea of attaching all the information as metadata. I used it to annotate all of our photos.

However, all of our relatives were not overly pleased with its interface. I knew that if I was going to write or adapt someone elses picture viewer I needed to be able to access the metadata programatically. I tried looking into the DLLs used by Photo Tools Pro but lack the experience and skill to get into it like you did.

My searches across the internet were fruitless until MS released the Code Pack. With that I could reach all the items I want to use with the exception of Headline.

That is the one thing that really irks me about MS. Their inconsistancy across products. None of their products are consistent in how they handle metadata. 'Headline' being a prime example (tho I am sure not the only example). Their different groups don't talk to each other or share information.

I didn't get heavily into disecting the xml file but it looks like it follows the 'Policy'. I would love to see the code that utilizes the xml file to do all of the dirty work.

Don't know if I want to use your method or mine. It will depend on how easy it is to extract the actual data from the returned field. I look forward to seeing your added code.

Thanks for sharing and I added my score of five.
GeneralRe: Decoding the metadata Pin
Dexter Legaspi29-Oct-09 8:03
Dexter Legaspi29-Oct-09 8:03 
GeneralRe: Decoding the metadata Pin
rctaubert29-Oct-09 11:39
rctaubert29-Oct-09 11:39 
GeneralRe: Decoding the metadata Pin
Dexter Legaspi29-Oct-09 15:04
Dexter Legaspi29-Oct-09 15:04 
GeneralRe: Decoding the metadata Pin
rctaubert31-Oct-09 3:04
rctaubert31-Oct-09 3:04 
GeneralRe: Decoding the metadata Pin
Dexter Legaspi31-Oct-09 4:35
Dexter Legaspi31-Oct-09 4:35 
GeneralRe: Decoding the metadata Pin
Steini kallinn6-Nov-09 5:25
Steini kallinn6-Nov-09 5:25 
GeneralRe: Decoding the metadata Pin
Dexter Legaspi6-Nov-09 5:35
Dexter Legaspi6-Nov-09 5:35 
QuestionError on loading policy file [modified] Pin
andrewward27-Oct-09 13:05
andrewward27-Oct-09 13:05 
AnswerRe: Error on loading policy file Pin
Dexter Legaspi27-Oct-09 14:18
Dexter Legaspi27-Oct-09 14:18 
AnswerRe: Error on loading policy file Pin
jbahnsen18-Jan-10 9:06
jbahnsen18-Jan-10 9:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.