I keep getting errors with WritableBitmap and LoadAsync()

Jan 20, 2014 at 11:23 AM

I have been looking at this Toolkit and i think its pretty sweet but i have a few issues when im using code snipits from the class WriteableBitmapFromBitmapImageExtension in WinRTXamlToolkit (Windows 8.1).

The main error that i am getting alot is

'Windows.UI.Xaml.Media.Imaging.WriteableBitmap' does not contain a definition for 'LoadAsync' and no extension method 'LoadAsync' accepting a first argument of type 'Windows.UI.Xaml.Media.Imaging.WriteableBitmap' could be found (are you missing a using directive or an assembly reference?

I have added the reference WinRTXamlToolkit.dll in my project.

Any help would be greatly appreciated.

Jan 20, 2014 at 3:57 PM
You need to add

using WinRTXamlToolkit.Imaging;

for the compiler to see the extension method in WriteableBitmapFromBitmapImageExtension, which allows to load a WriteableBitmap from a BitmapImage.

Note that the error you are getting is about trying to load one from a WriteableBitmap and I don't yet have an extension method to do that as a LoadAsync method. You can use WriteableBitmapCopyExtensions.Copy() for that though.

Also note that LoadAsync(BitmapImage) is fairly limited in that it loads the image from the UriSource of the BitmapImage, which might not be set in some conditions - e.g. if you loaded the BI using SetSource(stream) method. Finally note that this will likely cause an image to be downloaded and decoded again, which is not very efficient and you might be better off having it loaded to a WriteableBitmap in the first place and copying it if you really need different versions of the image.
Jan 20, 2014 at 5:02 PM

Thanks for your quick response.

adding using WinRTXamlToolkit.Imaging; did fix my problem

so this is my code at the moment,
                bitmapStream = await this.sharedBitmapStreamRef.OpenReadAsync();
                BitmapImage bitmapImage = new BitmapImage();
                sourceImage.Source = bitmapImage;

                WriteableBitmap bitmapToSave = await BitmapTransfer.FromBitmapImage(bitmapImage);
At the moment it outputs an image which it displays nothing. In your last paragraph you did say that it is efficient to have it loaded in a WritableBitmap in the first place as it would be more efficient, any ways on going about to do this?
Jan 20, 2014 at 6:54 PM
Yes, as I said - if you load a BitmapImage using SetSource~() methods - the UriSource isn't set. The way the method that loads a WB from a BI works is it just uses that UriSource to load the WB from the original source. There is no API unfortunately to read the pixels out of a BitmapImage (well, maybe not true these days since you can use RenderTargetBitmap and render a BitmapImage to a RenderTargetBitmap and then copy the pixels, but that's also not very efficient and kind of hacky since it requires the UI to actually be inserted into the visible UI tree).

In your case you would just do a string-replace of all BitmapImage strings in your code to WriteableBitmap and replace the BitmapTransfer.FromBitmapImage() call with a bitmapImage.Copy() call that is using the WriteableBitmapCopyExtensions.Copy() extension method.

Alternatively you can leave the first paragraph of your code intact and do the following in the second part to load the image again:
var bitmapToSave = new WriteableBitmap(1,1);
await bitmapToSave.SetSourceAsync(bitmapStream);
Also remember to wrap your "bitmapStream = await this.sharedBitmapStreamRef.OpenReadAsync()" code in a using block to properly close the stream when done with it. That also requires that you replace the SetSource() calls with await SetSourceAsync() so that the images are actually decoded before you close the stream.

The choice between loading the image again vs copying the pixels of an already existing one should be based on some performance tuning - you'd need to check which one works faster in your scenario.