UPDATE 7/10/2009: See THIS BLOG POST regarding Silverlight 3 RTW, we can now read the Pixels after calling Render()!
Ok, the title of this post is a tease. Read on and find out why!
A new feature in Silverlight 3 Beta 1 is the WriteableBitmap class, which allows pixel-level image manipulation at runtime. It turns out you can also do pixel-level image manipulation in Silverlight 2, using methods such as Joe Stegman’s Editable Image samples. But there are some new features to WriteableBitmap which weren’t possible using these methods.
First, you can use WriteableBitmap to render a portion of the Visual Tree to a bitmap.
WriteableBitmap wb = new WriteableBitmap(800, 600, PixelFormats.Bgr32);
wb.Render(canvas1, new TranslateTransform());
…you can then assign the WriteableBitmap to the Source value of an Image like so:
img.Source = wb;
HitTest a Raster (Bitmap) Image in Silverlight 3
In a previous blog post, I showed how you could use the VisualTreeHelper.FindElementsInHostCoordinates to do a HitTest on a XAML element in Silverlight 2. But in Silverlight 2, there was no way of doing a HitTest on a Raster (Bitmap) image, which makes it difficult to do collision detection on Image elements.
In Silverlight 3, WriteableBitmap will “eventually” make this possible because you can access Pixels of the WriteableBitmap at runtime! Unfortunately, in Beta 1 of Silverlight 3, this functionality is disabled in most cases L The reason being that there needs to be security put into place to ensure that a hacker could not request 3rd party images through a Silverlight app and then access secure information.
So say you have an image which you plant on a Canvas like so:
<Image Source="/fish.png" x:Name="imgFish" />
And then you can set up a WriteableBitmap as follows:
BitmapSource bitmapSource = imgFish.Source as BitmapSource;
WriteableBitmap wb = new WriteableBitmap(bitmapSource);
… In Silverlight 3 BETA 1, this will actually bring back the correct PixelWidth and PixelHeight into bmPixels1,but when you try to access the pixel array, you will get a Null Reference Exception:
int x = wb[x]; // gives a Null Ref
Also, after calling the Render method on WriteableBitmap (such as in the previous example to render the visual tree), the pixel array will be unavailable and will give a Null Reference Exception.
Oh well… Silverlight 3 _is_ a Beta at this point, so we can only hope this functionality will be available by RTM!