Silverlight : BitmapImage to WriteableBitmap
I can successfully load the following Bitmap like this and display it within an Image control on the view.
var bitmapImage = new BitmapImage
{
UriSource =
new Uri("../Images/Test.JPG", UriKind.Relative)
};
However as soon as I add this line to create a WriteableBitmap out of the bitmap,
var w = new WriteableBitmap(bitmapImage);
I get a Runtime error at the line above: "Object reference not set to an instance of an object."
It seems the BitmapImage creation is delayed, could that be? How should I fix this?
Update:
I am now trying this but the openImage seems never to be hit. (even without trying to make it synchronous, it still fails) What is wrong here?
var image = new BitmapImage();
image.ImageOpened += (sender, args) => resetEventBitmap.Set();
image.ImageFailed += (o, eventArgs) =>
{
开发者_JAVA百科 resetEventBitmap.Set();
throw eventArgs.ErrorException;
};
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
image.UriSource = uri;
resetEventBitmap.WaitOne();
Thanks,
Reference: http://www.blog.ingenuitynow.net/Silverlight+Creating+A+WriteableBitmap+From+A+Uri+Source.aspx
Basically, bitmap image has a dependency property "CreateOptions" which, by default, is set to "DelayCreation". This causes the bitmap to be delayed for rendering until after it's needed. Hence, this causes our "object reference not set to an instance of an object" error. To fix this, we have to break the bitmap creation out of the writeablebitmap constructor, change this option, and then put it back in. In vb.net this looks like:
Dim tmpUri As New Uri(yourpath.ToString)
Dim bmp As New BitmapImage
bmp.CreateOptions = BitmapCreateOptions.None
bmp.UriSource = tmpUri
Dim wb As New WriteableBitmap(bmp)
BitmapImage _classField;
void LoadImageFunction()
{
_classField = new BitmapImage();
_classField.ImageOpened += new EventHandler<RoutedEventArgs>(bi_ImageOpened);
_classField.ImageFailed += new EventHandler<ExceptionRoutedEventArgs>(bi_ImageFailed);
//sorry.. totally forgot about order :)
_classField.UriSource = new Uri("../some/uri", UriKind.Relative);
}
void bi_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
//something has happend
throw e.ErrorException;
}
void bi_ImageOpened(object sender, RoutedEventArgs e)
{
//image is loaded.. now we can work with it..
var w = new WriteableBitmap(_classField);
}
img1 = new BitmapImage(new Uri("/PrjName;component/Images/image01.jpg", UriKind.RelativeOrAbsolute));
img2 = new BitmapImage(new Uri("/PrjName;component/Images/image02.jpg", UriKind.RelativeOrAbsolute));
img1.CreateOptions = BitmapCreateOptions.None;
img2.CreateOptions = BitmapCreateOptions.None;
img1.ImageOpened += new EventHandler<RoutedEventArgs>(img1_ImageOpened);
img2.ImageOpened += new EventHandler<RoutedEventArgs>(img2_ImageOpened);
void img2_ImageOpened(object sender, RoutedEventArgs e)
{
load2 = true;
}
void img1_ImageOpened(object sender, RoutedEventArgs e)
{
load1 = true;
}
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
while (!load1 && !load2)
{ }
WriteableBitmap x = new WriteableBitmap(img1);
WriteableBitmap y = new WriteableBitmap(img2);
}
This should work. it did for me..! It makes it a lil' complicated, but that's how it works!
精彩评论