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... }
_, I will recommend this site to other people that I am aware of with the same that would be interested.
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.
THANK YOU SO MUCH!!! I’m a win phone 7 noob and it’s taken me so long to get this extremely simple task working… you’ve saved my throwing my PC out the window. Cheers
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
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
Thank you, I spent a whole f*cking day because of the delay thing !