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!

6 thoughts on “Silverlight: Creating a WriteableBitmap from a Uri Source

  1. I had the exactly same code and the same problem as Pete. I’ve taken your suggestion to Pete but it didn’t work. It still throws an error: Object reference not set to an instance of an object.

    Reply
  2. Pete,

    In the sample above, I show how to "wait" for the image to load using the ImageOpened event. I suspect that the image just takes a bit longer to load. I think that BitmapCreateOptions.None means that the image tries to load immediately. Tries, but I don’t know if it waits around for the Uri to return successfully. By handling the ImageOpened event you give the application the chance to deal with the image load asynchronously. Again, I am not positive about this, just an assumption. Also, double check your Url to make sure it is valid, but you probably did that already.

    Please let me know if that works out.

    Good luck,
    Andy

    Reply
  3. Hey,

    So I have spent the better part of today trying to get my viewmodel code to work with the writeable bitmap. Think I am about to go crazy, seems so simple.
    Here is what I had, but it just returns a blank image:

    BitmapImage biDefault = new System.Windows.Media.Imaging.BitmapImage(new Uri("/images/section1/Chart.png", UriKind.Relative));
    System.Windows.Controls.Image i = new System.Windows.Controls.Image();
    i.Source = biDefault;
    bmpImage = new WriteableBitmap(i, new TranslateTransform());

    Now I went to this and it throws the nasty null reference exception again:

    Uri uri = new Uri("/images/section1/Chart.png", UriKind.Relative);
    BitmapImage bitmapImage = new BitmapImage(uri);
    bitmapImage.CreateOptions = BitmapCreateOptions.None;
    bitmapImage.UriSource = uri;
    bmpImage = new WriteableBitmap(bitmapImage);

    You have any hints?

    Thanks

    Pete

    Reply

Leave a reply to Oswin Cancel reply

required

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>