Image.FromStream Doesn't Always Preserve Exif Data

Reading Exif files within C# is easy. For example, if you want to know camera model, it is enough to simply loop through image’s properties and read it:

private static string GetCameraModel(Image image) {
    foreach (var property in image.PropertyItems) {
        if (property.Id == ExifTag.CameraModel) { //0x0110
            return ASCIIEncoding.ASCII.GetString(property.Value).Trim('\0');
        }
    }
    return null; //no model found
}

However, if you want to do anything with the file you cannot simply load it with Image.FromFile as .NET keeps image open all the way until disposal. Easy enough, just load image with Image.FromStream, like this:

Image image;
using (var stream = new FileStream(this.File.FullName, FileMode.Open, FileAccess.Read)) {
    image = Image.FromStream(stream);
}
return GetCameraModel(image);

Image loaded in this manner will not contain any Exif - just the image data. The default stream loader just tossed everything that’s not picture away. If you want to preserve picture, you need to explicitly tell it:

Image image;
using (var stream = new FileStream(this.File.FullName, FileMode.Open, FileAccess.Read)) {
    image = Image.FromStream(stream, useEmbeddedColorManagement: true, validateImageData: true);
}
return GetCameraModel(image);

Now you can read all the Exif data you can handle. :)


PS: Interestingly, it seems that on Windows 7 it works either way.