3

I have a PNG file stored in my cloud in blob storage, I want to download it and render it on the screen in WPF.

I know about the Dispatcher and Freezing, but nothing is working. I keep getting the error about "another thread owns it".

Here is what I have:

var decoder = GetDecoder("http://address/image.png");

Dispatcher.Invoke(DispatcherPriority.Send, new Action<BitmapFrame>(SetImage), decoder.Frames[0]);

public void SetImage(BitmapFrame source)
{
    var bitmapFrame = BitmapFrame.Create(source);  //ERROR HERE!!!!!!!!
    LazyImage.Source = bitmapFrame;
}

private BitmapDecoder GetDecoder(object uri)
{
    var extension = System.IO.Path.GetExtension((string)uri);
    BitmapDecoder decoder = null;
    if (extension.ToLower() == ".png")
        decoder = BitmapDecoder.Create(new Uri((string)uri, UriKind.Absolute), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
    return decoder;
}

If i try to freeze the Frame[0] I get an exception saying that this Frame cannot be frozen. Also the Decoder returned by BitmapDecoder.Create is not a PngBitmapDecoder but a LateBoundBitmapDecoder which I dont really know how to use effectively.

3 Answers 3

5

In brief: try wrapping the result into a WriteableBitmap.

Long story, with code.

Sign up to request clarification or add additional context in comments.

1 Comment

For my case, this was the only solution that worked. I needed to feed a BitmapFrame into a TransformedBitmap. Didn't have control over which thread the BitmapFrame was created on as it is provided by a library (and BitmapFrame's Dispatcher property is null). Even querying the CanFreeze property caused an exception. I had two options: major overhaul of the source code of mine and others, or use WriteableBitmap. Guess which one i chose...
1

Its possible that you need to not only create the Bitmapframe on the dispatcher but also the BitmapDecoder? Have you tried invoking the GetDecoder on the dispatcher?

5 Comments

perhaps, I think the creation of the decoder is a synchronous operation which means that I would like to avoid it happening on the UI thread. Mind you, files on my local PC (not http URL's) works fine as it is, because the decoder is a PngBitmapDecoder
Well... its possible that maybe you can call BitmapFrame.Create() in a thread, and attempt to freeze the frame it returns?
If I freeze the frame returned by the LateBoundBitmapDecoder, I get an exception, but if I use a local URL (and hence the PngBitmapDecoder) I can freeze it and it works just fine.
Was lookin around and found this: social.msdn.microsoft.com/Forums/en-US/wpf/thread/… Scroll down to Dwayne Need's answer, he has some source for a demo that does async loading, which should bypass the issue you are having.
Ok, looks like my issues were larger related to the fact that I created a BitmapImage on a BG thread and tried to pass it to a UI thread, but for some reason I could not clone or freeze it, so I just ended up passing a byte[] to the UI thread and contructing an image using that... Ill give you the points because you were the only one who answered
1

This is still a problem today! Wrapping the data in WriteableBitmap as suggested by Bohdan will work, but that type has a front and back buffer which doubles its memory footprint. CachedBitmap is a better choice.

new CachedBitmap(bitmapSource, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);

Use BitmapCacheOption.OnLoad unless you like surprises, and remember to freeze the resulting object too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.