Getting metadata from an image c#

3

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?

c#
multithreading
metadata
asked on Stack Overflow May 27, 2014 by user1 • edited Apr 18, 2018 by i_saw_drones

2 Answers

2

No, you don't HAVE to use BitmapCacheOption.OnLoad.

You just have to not use BitmapCacheOption.None.

  • Default: Caches the entire image into memory. This is the default value.
  • None: Do not create a memory store. All requests for the image are filled directly by the image file.
  • OnDemand: Creates a memory store for requested data only. The first request loads the image directly; subsequent requests are filled from the cache.
  • OnLoad: Caches the entire image into memory at load time. All requests for image data are filled from the memory store.

So, basically you may use

BitmapDecoder sourceDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.Default);

More about BitmapCacheOption

answered on Stack Overflow May 27, 2014 by kiwixz
0

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?

answered on Stack Overflow May 27, 2014 by user1

User contributions licensed under CC BY-SA 3.0