I am trying to import an image into my WPF application and upon clicking the save button save the image and its metadata to a different location.
I currently have:
BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;
BitmapMetadata importedMetaData = new BitmapMetadata("jpg");
using (Stream sourceStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
{
BitmapDecoder sourceDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.None);
// Check source is has valid frames
if (sourceDecoder.Frames[0] != null && sourceDecoder.Frames[0].Metadata != null)
{
sourceDecoder.Frames[0].Metadata.Freeze();
// Get a clone copy of the metadata
BitmapMetadata sourceMetadata = sourceDecoder.Frames[0].Metadata.Clone() as BitmapMetadata;
importedMetaData = sourceMetadata;
}
}
if (!Directory.Exists(Settings.LocalPhotoDirectory))
{
Directory.CreateDirectory(Settings.LocalPhotoDirectory);
}
string photoPath = Path.Combine(Settings.LocalPhotoDirectory, this.BasicTags.ElementAt(8).Value.ToString());
if (!Directory.Exists(photoPath))
{
Directory.CreateDirectory(photoPath);
}
string localfileName = Path.Combine(photoPath, PhotoId.ToString() + ".jpg");
string fileName = Path.Combine(this.Settings.QueueFolder, PhotoId.ToString() + ".jpg");
using (FileStream stream = new FileStream(fileName, FileMode.Create))
{
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.QualityLevel = this.Settings.ImageQuality;
encoder.Frames.Add(BitmapFrame.Create(Photo, null, importedMetaData, null));
encoder.Save(stream);
}
where Photo
is a BitmapSource
and fileName
is the filename of the photo.
But my code keeps crashing at the encoder.Save
lin. with the following error:
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in PresentationCore.dll
additional information: The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))
This whole method is being run as a STA thread as I read you must access the BitmapMetadata
class using an STA thread. But still no luck. What am I doing wrong?
No, you don't HAVE to use BitmapCacheOption.OnLoad.
You just have to not use BitmapCacheOption.None.
So, basically you may use
BitmapDecoder sourceDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.Default);
I found the problem. The problem lay with the line
BitmapDecoder sourceDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.None);
it works if you change it to
BitmapDecoder sourceDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.OnLoad);
Not sure why? maybe someone could explain?
User contributions licensed under CC BY-SA 3.0