Silverlight 3’s New Writeable Bitmap

Another of the exciting new features coming in Silverlight 3 is the WriteableBitmap class. Silverlight 2 had no API for creating bitmaps, but WriteableBitmap makes creating bitmaps on the fly easy as pie. In Beta 1, you can create bitmaps from scratch, but you can’t (yet) edit existing bitmaps–for example, bitmaps assigned to XAML images or loaded from the local hard disk. Expect that to change once Microsoft has had time to fully ponder the security implications of editing bitmaps and can lock down the API to prevent malicious applications from exploiting this feature.

To demonstrate how WriteableBitmap works, I built a Silverlight 3 fractal viewer that creates images of the Mandelbrot set on the client using the same basic algorithm that the Deep Zoom fractal viewer I blogged about last week uses to generate fractal images on the server. Here are some screen shots from the Silverlight 3 version:

Silverlight 3 Mandelbrot (1)Silverlight 3 Mandelbrot (2)Silverlight 3 Mandelbrot (3)

The work of drawing the Mandelbrot set is peformed by a helper method named DrawMandelbrotSet, which takes as parameters a reference to a XAML Image object, the coefficients of the equation that describes the horizontal and vertical extents of the region of the set to be rendered, and the desired width and height of the generated bitmap. Here’s the source code:

private void DrawMandelbrotSet(Image image, double rmin, double rmax,

    double imin, double imax, int width, int height)

{

    // Create a WriteableBitmap

    WriteableBitmap bitmap = new WriteableBitmap(width, height, PixelFormats.Bgr32);

    bitmap.Lock();

 

    // Compute increments for real and imaginary components

    double dr = (rmax – rmin) / (width – 1);

    double di = (imax – imin) / (height – 1);

 

    // Check each pixel for inclusion in the Mandelbrot set

    for (int x = 0; x < width; x++)

    {

        double cr = rmin + (x * dr);

 

        for (int y = 0; y < height; y++)

        {

            double ci = imin + (y * di);

            double zr = cr;

            double zi = ci;

            int count = 0;

 

            while (count < _max)

            {

                double zr2 = zr * zr;

                double zi2 = zi * zi;

 

                if (zr2 + zi2 > _escape)

                {

                    bitmap[(y * width) + x] = ColorMapper.GetColor(count, _max);

                    break;

                }

 

                zi = ci + (2.0 * zr * zi);

                zr = cr + zr2 – zi2;

                count++;

            }

 

            if (count == _max)

                bitmap[(y * width) + x] = 0; // Black

        }

    }

 

    bitmap.Invalidate();

    bitmap.Unlock();

 

    // Copy the WriteableBitmap bits to the XAML Image

    image.Source = bitmap;

}

The individual pixels in the bitmap are exposed through WriteableBitmap’s indexer: bitmap[0] is the first pixel (the one in the upper left corner), bitmap[1] is the second pixel (the one to the right of bitmap[0]), and so on. It’s hard to imagine how the API could be much simpler than that.

This is one of many Silverlight 3 samples I’ll be presenting at Devscovery next month in New York. In fact, I’m doing an entire session on all the new stuff in Silverlight 3, so I’d love to see you there! I’ll be posting the source code for most of these samples a little later, but I’m going to hold off until after Devscovery so Devscovery attendees are the first to receive them.

We deliver solutions that accelerate the value of Azure.

Ready to experience the full power of Microsoft Azure?

Start Today

Blog Home

Stay Connected

Upcoming Events

All Events