Of course, I couldn't just "accept" that. Unfortunately, the work-around is a bit of a hack, but it does work reliably!
So, in the following example, assume that I have a RenderTargetBitmap from WPF...
JpegBitmapEncoder imageEncoder = new JpegBitmapEncoder { QualityLevel = 100 }; imageEncoder.Frames.Add(BitmapFrame.Create(renderTarget)); using (MemoryStream memoryStream = new MemoryStream()) { imageEncoder.Save(memoryStream); memoryStream.Position = 0; JpegBitmapDecoder decoder = new JpegBitmapDecoder(memoryStream, BitmapCreateOptions.None, BitmapCacheOption.Default); BitmapFrame frame = decoder.Frames[0]; BitmapMetadata metadata = (BitmapMetadata) frame.Metadata.Clone(); metadata.Subject = "This is a test subject."; metadata.Title = "This is a test title."; metadata.Comment = "This is a test comment."; imageEncoder = new JpegBitmapEncoder() { QualityLevel = 100 }; imageEncoder.Frames.Add(BitmapFrame.Create((BitmapSource)frame, (BitmapSource)frame.Thumbnail, metadata, frame.ColorContexts)); using (var fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create)) { imageEncoder.Save(fileStream); } }
This is, of course, a hack -- it saves the image to the memory stream and then is capable of creating a "good" metadata object (normally, this blows up in your face if you try to send one in that you created on the fly).
Now, you can set it up however you like -- go nuts!