.NET Framework Class Library
BitmapMetadata Class

Provides support for reading and writing metadata to and from a bitmap image.

Namespace:  System.Windows.Media.Imaging
Assembly:  PresentationCore (in PresentationCore.dll)
Syntax

Visual Basic (Declaration)
Public Class BitmapMetadata _
    Inherits ImageMetadata _
    Implements IEnumerable(Of String), IEnumerable
Visual Basic (Usage)
Dim instance As BitmapMetadata
C#
public class BitmapMetadata : ImageMetadata, 
    IEnumerable<string>, IEnumerable
Visual C++
public ref class BitmapMetadata : public ImageMetadata, 
    IEnumerable<String^>, IEnumerable
JScript
public class BitmapMetadata extends ImageMetadata implements IEnumerable<String>, IEnumerable
XAML
You cannot directly create an instance of this class in XAML.
Remarks

Metadata that is associated with an image is data that describes the image but is not necessary to display the image. Each supported bitmap image format handles metadata differently, but the facility for reading and writing metadata is the same.

Windows Presentation Foundation (WPF) supports the following image metadata schemas: Exchangeable image file (Exif), tEXt (PNG Textual Data), image file directory (IFD), International Press Telecommunications Council (IPTC), and Extensible Metadata Platform (XMP).

If a BitmapMetadata is exposed by a BitmapFrame that is obtained by using a BitmapDecoder, it is read-only by default and mutable operations will throw an exception. If it is exposed by a BitmapFrame that wraps another BitmapSource, it is mutable on construction.

The SetQuery and GetQuery methods can be used to construct and read metadata queries.

Examples

The following example demonstrates how to write metadata to a Tagged Image File Format (TIFF) image by using the IFD and Exif schemas.

Visual Basic
Dim tiffMetadata As New BitmapMetadata("tiff")
tiffMetadata.SetQuery("/ifd/{ushort=1000}", 9999)
tiffMetadata.SetQuery("/ifd/{uint=1001}", 23456)
tiffMetadata.SetQuery("/ifd/{uint=1002}", 34567)
tiffMetadata.SetQuery("/ifd/PaddingSchema:padding", CType(4096, UInt32))
tiffMetadata.SetQuery("/ifd/exif", New BitmapMetadata("exif"))
tiffMetadata.SetQuery("/ifd/exif/PaddingSchema:padding", CType(4096, UInt32))
C#
BitmapMetadata tiffMetadata = new BitmapMetadata("tiff");
tiffMetadata.SetQuery("/ifd/{ushort=1000}", 9999);
tiffMetadata.SetQuery("/ifd/{uint=1001}", 23456);
tiffMetadata.SetQuery("/ifd/{uint=1002}", 34567);
tiffMetadata.SetQuery("/ifd/PaddingSchema:padding", (UInt32)4096);
tiffMetadata.SetQuery("/ifd/exif", new BitmapMetadata("exif"));
tiffMetadata.SetQuery("/ifd/exif/PaddingSchema:padding", (UInt32)4096);
Inheritance Hierarchy

System..::.Object
  System.Windows.Threading..::.DispatcherObject
    System.Windows..::.DependencyObject
      System.Windows..::.Freezable
        System.Windows.Media..::.ImageMetadata
          System.Windows.Media.Imaging..::.BitmapMetadata
            System.Windows.Media.Imaging..::.InPlaceBitmapMetadataWriter
Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
Platforms

Windows 7, Windows Vista, Windows XP SP2, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Version Information

.NET Framework

Supported in: 3.5, 3.0
See Also

Reference

Other Resources

Tags :


Community Content

jader3rd
I wasn't able to modify image metadata using this class

I would have saved a day of hassle if I had discovered the InPlaceMetaDataWriter (http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.inplacebitmapmetadatawriter.aspx) earlier.

Tags :

Thomas Lee
Better Examples

One note about the comment above, the InPlaceMetadataWriter will not work unless there's enough padding in the header of your image. If you are creating a new Metadata block, it will not work either. The above example is fairly anemic here are some more fleshed out examples. Also, see this page for better resources on data tags: http://msdn.microsoft.com/en-us/library/bb643802.aspx

The following example shows the way to "Un-Freeze" the metadata block. This will cause the image to be re-encoded but that's the price that must be paid to add metadata if there isn't enough room in the header. Follow this pattern for other image types.

// Get the source image stream
using (FileStream imageFileStream =
    new FileStream("test.jpg", FileMode.Open))
{
    // Load the image in the decoder
    JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageFileStream,
        BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    
    // Make a copy of the frame, this will also unlock the metadata
    BitmapFrame frameCopy = BitmapFrame.Create(decoder.Frames[0]);
 
    // Now we have a metadata object that is unfrozen
    BitmapMetadata copyMetadata = (BitmapMetadata)frameCopy.Metadata;
 
    // Set your metadata here, metadata in the source frame
    // will be rewritten to the output frame and any changes
    // will overwrite the metadata in the source frame.
    copyMetadata.Title = "Test Title";
 
    // Create a new encoder and add the copied frame to it
    JpegBitmapEncoder encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(frameCopy);
 
    // Save the new file with the new metadata
    using (FileStream imageFileOutStream =
        new FileStream("testOutput.jpg", FileMode.Create))
    {
        encoder.Save(imageFileOutStream);
    }
}
 
// If you want to add a brand new metadata block, you must create
// the metadata block first and then pass the metadata to the
// BitmapFrame.Create method so it's written to the frame
 
// Get the source image stream
using (FileStream imageFileStream =
    new FileStream("test.jpg", FileMode.Open))
{
    // Create new metadata first, here we are making an IPTC block in a JPG
    // NOTE: IPTC tags do not get parsed correctly on Windows 7
    BitmapMetadata jpgData = new BitmapMetadata("jpg");
    jpgData.SetQuery("/app13/irb/8bimiptc/iptc/object name", "Test Title");
    jpgData.SetQuery("/app13/irb/8bimiptc/iptc/keywords", "Test Tag");
    jpgData.SetQuery("/app13/irb/8bimiptc/iptc/date created", "20090512");
    jpgData.SetQuery("/app13/irb/8bimiptc/iptc/time created", "115300-0800");
    jpgData.SetQuery("/app13/irb/8bimiptc/iptc/caption", "Test Comment");
    jpgData.SetQuery("/app13/irb/8bimiptc/iptc/by-line", "Test Author");
    jpgData.SetQuery("/app13/irb/8bimiptc/iptc/copyright notice", "Copyright 2009");
 
    // Load the image in the decoder
    JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageFileStream,
        BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
 
    // Make a copy of the frame and also pass in the new metadata
    BitmapFrame frameCopy = BitmapFrame.Create(decoder.Frames[0],
        null /* thumbnail */,
        jpgData /* new metadata */,
        decoder.ColorContexts);
 
    // Now we have the image frame that has a fresh IPTC metadata block
 
    // Create a new encoder and add the frame to it
    JpegBitmapEncoder encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(frameCopy);
 
    // Save the new file with the new metadata
    using (FileStream imageFileOutStream =
        new FileStream("testOutput2.jpg", FileMode.Create))
    {
        encoder.Save(imageFileOutStream);
    }
}
 
// Example of TIFF with EXIF
BitmapMetadata tiffData = new BitmapMetadata("tiff");
tiffData.SetQuery("/ifd/{ushort=40091}",
    UnicodeEncoding.Unicode.GetBytes("Test Title".ToCharArray()));
tiffData.SetQuery("/ifd/{ushort=40094}",
    UnicodeEncoding.Unicode.GetBytes("Test Tag".ToCharArray()));
tiffData.SetQuery("/ifd/exif/{uint=36867}", "2009:05:12 11:53:00");
tiffData.SetQuery("/ifd/{ushort=40092}",
    UnicodeEncoding.Unicode.GetBytes("Test Comment".ToCharArray()));
tiffData.SetQuery("/ifd/{ushort=40093}",
    UnicodeEncoding.Unicode.GetBytes("Test Author".ToCharArray()));
tiffData.SetQuery("/ifd/{ushort=33432}", "Copyright 2009");
 
// Example of WDP (Windows Media Photo) with XMP
// NOTE: This does not work (throws COM Exception) on x64
wdpMetadata = new BitmapMetadata("wmphoto");
 
// With XMP, you need to create the XMP nodes before you use them
// The BitmapMetadata constructor will accept metadata block types as
// well as image types as shown below
wdpMetadata.SetQuery("/ifd/xmp", new BitmapMetadata("xmp"));
wdpMetadata.SetQuery("/ifd/xmp/dc:title", new BitmapMetadata("xmpalt"));
wdpMetadata.SetQuery("/ifd/xmp/exif:UserComment", new BitmapMetadata("xmpalt"));
wdpMetadata.SetQuery("/ifd/xmp/dc:rights", new BitmapMetadata("xmpalt"));
wdpMetadata.SetQuery("/ifd/xmp/dc:creator", new BitmapMetadata("xmpseq"));
wdpMetadata.SetQuery("/ifd/xmp/dc:subject", new BitmapMetadata("xmpbag"));
 
// XMP Alt has a default value x-default where you can set the value
wdpMetadata.SetQuery("/ifd/xmp/dc:title/x-default", "Test Title");
wdpMetadata.SetQuery("/ifd/xmp/exif:UserComment/x-default", "Test Comment");
wdpMetadata.SetQuery("/ifd/xmp/dc:rights/x-default", "Copyright 2009");
 
// XMP Seq/XMP Bag are indexed.  You can set multiple values using {ulong=<offset>}
wdpMetadata.SetQuery("/ifd/xmp/dc:creator/{ulong=0}", "Test Author 1");
wdpMetadata.SetQuery("/ifd/xmp/dc:creator/{ulong=1}", "Test Author 2");
wdpMetadata.SetQuery("/ifd/xmp/dc:subject/{ulong=0}", "Test Tag");
 
// This value is at the root of the XMP block using the XMP date format
wdpMetadata.SetQuery("/ifd/xmp/xmp:CreateDate", "2009-05-12T12:05:05");
 
Tags : sample

Thomas Lee
Info--------!

Any thing like this for .NET 2.0

[tfl - 18 05 09] Hi - and thanks for your post. You should post questions like this to the MSDN Forums at http://forums.microsoft.com/msdn or the MSDN Newsgroups at http://www.microsoft.com/communities/newsgroups/en-us/. You are much more likely get a quicker response using the forums than through the Community Content. For specific help about:
Visual Studio  : http://groups.google.com/groups/dir?sel=usenet%3Dmicrosoft.public.vstudio%2C&
.NET Framework : http://groups.google.com/groups/dir?sel=usenet%3Dmicrosoft.public.dotnet.framework
All Public     : http://groups.google.com/groups/dir?sel=usenet%3Dmicrosoft.public%2C&


Page view tracker