Bitmap Coding and Metatdata in WPF
Written by Administrator   
Wednesday, 10 February 2010
Article Index
Bitmap Coding and Metatdata in WPF
Coding bitmaps
Reading metadata
Writing metadata

Writing metadata

You can, in theory, use SetQuery or any of the standard properties to change the value of metadata  but notice that some values are treated as read-only by the system and hence aren't writeable in principle. There is also the problem that the entire BitmapMetadata object is set to frozen, and this stops any modification to the metadata.

You can unfreeze the BitmapFrame object simply by cloning it - but this doesn't reset the BitmapMetadata property to be Frozen=false i.e. the metadata is still frozen. The solution is to clone the metadata separately from the BitmapFrame. Following this you can change some properties directly and some using SetQuery as appropriate.

For example, to set the author metadata and the Camera model you can use:

 BitmapMetadata tempMeta =
(BitmapMetadata)MyBMF.Metadata.Clone();
 string[] values = { "New author" };
tempMeta.Author = new
System.Collections.ObjectModel.
ReadOnlyCollection<string>(values);
tempMeta.CameraModel = "MyCamera";

Once you have customised the metadata you can use as the metadata for a new BitmapFrame created using the existing BitmapFrame:

 BitmapFrame NewBMF = BitmapFrame.Create(
(BitmapSource)MyBMF,
(BitmapSource)MyBMF.Thumbnail,
tempMeta,MyBMF.ColorContexts);

Once you have done this you can save a new copy of the file complete with the new metadata:

 JpegBitmapEncoder MyJpgEnc = new 
JpegBitmapEncoder();
 MyJpgEnc.Frames.Add(NewBMF);
FileStream fs = new FileStream(
"MyNewJpeg.jpg", FileMode.Create);
MyJpgEnc.Save(fs);

This all works but it has the huge disadvantage that you have to create a new copy of the file. You could, of course delete the old version and rename the new to give the impression that only the metadata had changed but, and this is a very big but, the image quality of any lossy compression would get worse each time you repeated the operation.

In-place writing

As an alternative to re-writing the file we can try an in-place writer which attempts to update the metadata without re-writing the entire file.

To make use of this the original file has to be opened as a modifiable stream:

 Stream jpegStream = new FileStream(
"MyJpeg.jpg", FileMode.Open,
FileAccess.ReadWrite,
FileShare.ReadWrite);
JpegBitmapDecoder MyJpegDec = new
JpegBitmapDecoder(jpegStream,
BitmapCreateOptions.None,
BitmapCacheOption.Default);

The cache option also has to be set to either default or onDemand.

Now we can create an InPlaceBitmapMetadataWriter associated with the frame and the stream it derives from:

 BitmapFrame MyBMF = MyJpegDec.Frames[0];
InPlaceBitmapMetadataWriter IPW = MyBMF.
CreateInPlaceBitmapMetadataWriter();

Following this we can set properties as the InPlaceBitmapMetadataWriter is derived directly from BitmapMetaData. You can use SetQuery or simply assign to standard properties. For example:

 IPW.Title = "My Picture";
 IPW.Comment = "a nice picture";
 IPW.CameraModel = "My camera";

Finally you can try the save and close the stream:

 IPW.TrySave();
 jpegStream.Close();

If the save worked the TrySave method returns true.

The main reason why the TrySave method fails is that the file has no more space for metadata, i.e. the allocated metadata space in the file is full. Many formats create metadata with "padding" which can be used to store new metadata and it is this that the InPlaceBitmapMetaData object makes use of. However this is a finite resource.

If the metadata space is full there is little you can do apart from recoding the file and accepting the enviable loss. This seems like a very silly restriction and there is no real reason why it isn't possible to copy the coded image part of the file without making any changes while updating the metadata.

If any one knows a .NET WPF way of doing this without opening up the file format email the editor.

The whole subject of metadata is complex and very difficult to get right, especially so when you move to non-image metadata.

Banner


Custom Bitmap Effects - HLSL

In the article Custom Bitmap Effects - Getting started we discovered how to work with HLSL in WPF. Now we are in a position to write more sophisticated shaders and  this means learning some more  [ ... ]



BitmapSource: WPF Bitmaps

Although bitmap graphics are not a main focus of WPF it does offer some useful facilities



Custom Shape

Creating a custom Shape isn't difficult but it does have some hidden gotchas. We take a look at how best to do the job.



Loading Bitmaps: DoEvents and the closure pattern

Sometimes loading a bitmap causes an asynchronous download and you have to wait for it to complete before using it - but how best to wait? The standard solution is to use an event but this breaks what [ ... ]



WPF .NET Core - Routed Events

Routed events are a key feature of WPF. We look at bubbling and tunnelling and how to create your own routed event and how WPF changes the underlying mechanics of Windows.


Other Articles

<ASIN:1430219106>

<ASIN:0470097744>

<ASIN:0979372518>

<ASIN:1590597826>

<ASIN:0596523572>



Last Updated ( Friday, 19 March 2010 )