Export Silverlight Visuals to Images


In a couple of my previous Silverlight projects I would have liked to export what a user saw on screen to an image that they could keep on their local machine. My last project involved creating diagrams and it would have been great to allow them to save them locally or to email them without having to fire up Silverlight. While this functionality is available in WPF, it was sadly missing from the Silverlight 2.0 platform. I had seen a number of proposed solutions such as loading your XAML in WPF at the server and rendering it there, none of which were tempting.

One of the new features in Silverlight 3.0 is a WriteableBitmap class. This is similar to it’s big brother in WPF and allows a developer to both render a visual to a bitmap and also be able to access it’s Pixel data. Great huh? Unfortunately although Silverlight 3.0 lets you render Visuals to a Bitmap and get at it’s pixel data, there is no easy way to save that Image locally.

I imagine the primary reason Microsoft introduced the WriteableBitmap in Silverlight 3.0 is so we can generate images dynamically and mess with it’s pixel data. Some of the clever bods in our community (Joe Stegman and Ian Griffiths) had already managed to achieve this functionality in Silverlight 2.0 by dynamically rendering a Png to a stream and getting Silverlight to display that. So if they can render a bunch of pixels to a Png, what’s stopping us from just rendering that to a file? As it turns out, nothing.

Using the Silverlight 3.0 WriteableBitmap I’m able to grab a Silverlight visual and render it to a Bitmap. Once I have the bitmap I can just take it’s Pixel data and run it through the PngGenerator created by Joe. With the rendered Png data we can ask the user where they would like to save the image and write it out to the resulting stream. I’ve rolled up this up into a single PngRenderer class so now you can simply pass it the element you would like to render and the stream you would like to render it to. Easy stuff.

var saveDialog = new SaveFileDialog
    {
        Filter = "Png Flies (*.png)|*.png"
    };

var result = saveDialog.ShowDialog();

if (result ?? false)
{
    using (var stream = saveDialog.OpenFile())
        PngRenderer.RenderElementToStream(MyPanel, stream);
}

This is an example rendering produced by this code. If you have Silverlight 3.0 why not take a look at a live sample.

SilverlightRender

This works and enables you to export an Image of a Silverlight visual locally to the user. So great huh? Unfortunately it kind of sucks, the Png that we’re writing is uncompressed so for even a moderately sized image it can easily reach file sizes of over a megabyte. Ideally we would write a compressed Png but as Silverlight doesn’t provide this functionality natively we would have to write it ourselves, I haven’t done this yet. If anyone feels like writing a managed Png encoder or knows one that already exists please let me know!

You can download the PngRenderer class and Joe’s PngGenerator class which it requires here.

Advertisements

One thought on “Export Silverlight Visuals to Images

  1. Hi,

    Nice write-up. Is there a way to export a Silverlight screen as a vectored image, such as an EPS or SVG?

    I need to professionally print large versions of my screens and soon. Remaking them in Illustrator fills me with woe.

    Thanks,
    Rich

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s