I was slightly surprised that google didn't turn up a solution to this one right off the bat, but it didn't, so here's my solution. I needed to extract metadata from some images, specifically the stuff which Windows Vista lets you edit from within the explorer - author, title, comments, that sort of thing. A quick check with PS suggests that these fields map variously back to the IPTC (IIM, legacy) and IPTC Core Exif fields; so long as you know which is which you can set the data in either place.
I recall from earlier work that IIS6 doesn'tnecessarily behave the same as IIS7 regarding the way the file system (NTFS) handles and presents extended properties; these days all my stuff is on the newer system so I don't care about IIS6.
There's not much to this, but you need to figure out which fields are which... I did this for the fields I care about in the code below. The file's data is utf-16 coded, which is slightly fiddily to deal with too.
/// <summary>
/// Class to read exif (MS Vista NTFS format - there are lots of formats) from an image file.
/// Reads the image data in once and parses it, then presents the results as properties of this class.
/// </summary>
private class ImageData
{
public string Title, Comments, Author, Name;
/// <summary>
/// Open the image and save the exif data I want.
/// </summary>
public ImageData(string shortName, string fileName)
{
Name = shortName.Replace(".jpg", ""); // Save this, so ...
Title = Name; // if no explicit title, use the filename as a title.
PropertyItem[] metadata = GetExifProperties(fileName);
foreach (PropertyItem item in metadata)
{
// Drop last 2 bytes, which are garbage.
string utf16String = UnicodeEncoding.Unicode.GetString(item.Value, 0, item.Len-2);
switch (item.Id)
{
// These I found by trial and error.
case 0x9C9B:
Title = utf16String;
break;
case 0x9C9C:
Comments = utf16String;
break;
case 0x9C9D:
Author = utf16String;
break;
default:
break;
}
}
}
public static PropertyItem[] GetExifProperties(string fileName)
{
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
using (System.Drawing.Image image = System.Drawing.Image.FromStream(stream))
return image.PropertyItems;
}
}
Use it like this, to instantiate a class which allows you to read the "Title" and other attributes."item" is a FileInfo object.
ImageData imgData = new ImageData( item.Name, item.FullName );