tags:

views:

3864

answers:

3

I am binding an Image.Source property to the result of the property shown below.

public BitmapSource MyImageSource
{
get
{
    BitmapSource source = null;

    PngBitmapDecoder decoder;
    using (var stream = new FileStream(@"C:\Temp\logo.png", FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        decoder = new PngBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);

        if (decoder.Frames != null && decoder.Frames.Count > 0)
            source = decoder.Frames[0];
    }

    return source;
}

}

For some reason this is failing during the rendering of the image (Deep in the PresentationCore assembly). I am certain the image is not corrupt as I can successfully show the same image w/o the binding

<Image Name="FooImage" Source="/logo.png" />

I have to bind the image source in code because I will eventually be creating the image stream from a base64 string.

Anyone know if this is a bug w/ WPF? or am I doing something incorrectly?

Thanks

A: 

Are you positive it's a PNG and not just a renamed Bitmap or Jpeg? If you create a new Bitmap image and then just rename it and change the file extension, this error is reproducible.

If I use a known PNG with your code, I don't get your issue, but a COM exception is thrown:

The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))

Can you try it out with a random PNG off the web and see if you get the same result?

KP Adrian
Right, this is the same exception I am getting, coming from > PresentationCore.dll!MS.Internal.HRESULT.Check(int hr) Line 1013 + 0xd bytes C#I get it w/ my image as well as a random png from the web.
+1  A: 

Also, have you tried just using a BitmapImage to load the image? It works fine with PNG, BMP, and JPEG.

It's also a specialized type of BitmapSource, so you could just replace your code in your property with this:

BitmapImage img = new BitmapImage(new Uri(@"C:\Temp\logo.png"));
return img;
KP Adrian
Your suggestion works but I need to eventually create this image from a base64 string, so I won't have a URI to simply create a BitmapImage from.
+2  A: 

The problem was the BitmapCacheOption option, changing to BitmapCacheOption.OnLoad works.

With BitmapCacheOption.None the BitmapSource isn’t decoded until the image is rendered, but the stream with the png in it is already disposed at that point. If you cache OnLoad, it’ll decode right away and cache the results, rather than trying to decode later when the stream no longer exists.

Oh thank God, I've been doing my head in for the last hour trying to work this out. Thanks!
gerrod