天天看點

[WP7]Silverlight: Creating a WriteableBitmap from a Uri Source

By : Andy Schwam

I’ve seen a few posts describing how to use a Uri as a source for a BitmapImage, and then the BitmapImage as the source for the WriteableBitmap.  But that didn’t work so well until I figured out the trick.  Here goes…

First, here is the code that I THOUGHT would work, but did not.

Uri uri = new Uri("http://somedomain.com/someimage.png");
BitmapImage bitmapImage = new BitmapImage(uri);
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);      

When you run that, you’ll most likely get an exception (I did) because the BitmapImage is not set when it is used for the WriteableBitmap.  My hypothesis was that the BitmapImage doesn’t render itself until it is needed.  I started looking through the properties of the BitmapImage, luckily there aren’t too many, when I came across the CreateOptions property – that sounded interesting!  It is an Enum with 3 values: DelayCreation, IgnoreImageCache, and None.  Guess which one is set as the default?  DelayCreation!  Here was my next pass at the code:

Uri uri = new Uri("http://somedomain.com/someimage.png");
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.CreateOptions = BitmapCreateOptions.None;
bitmapImage.UriSource = uri;
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);      

That’s it, pretty simple and it works.  But I took it one step further just in case.  I’m not positive this is necessary but I like to play it safe.  When inspecting the properties of the BitmapImage, I saw there is an ImageOpened event. I was thinking that some images may load slowly and I wasn’t sure if that happens asynchronously or not.  Would my application wait around for them to finish loading?  I don’t really know but it sure sounds like the ImageOpened event would be a way to make sure my images were loaded.  Here is my final take:

public void SomeMethod()
{
    Uri uri = new Uri("http://somedomain.com/someimage.png");
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.CreateOptions = BitmapCreateOptions.None;
    bitmapImage.ImageOpened += ImageOpened;
    bitmapImage.UriSource = uri;
}

void ImageOpened(object sender, RoutedEventArgs e)
{
    BitmapImage bm = (BitmapImage)sender;

    WriteableBitmap wbm = new WriteableBitmap(bm);

    //now I can use wbm for whatever I need...
}      

Good luck with your WriteableBitmaps!

繼續閱讀