The ability to allow a user to save a Flex chart, or in fact any Flex UI component, as an image has popped up on my radar several times over the last few years. Solutions to the problem have generally involved producing a pop-up window with the UI component as an image that the user can then save, either by bouncing the information off a server (James Ward - RIA Cowboy and Flex Cookbook) or interacting with JavaScript (Doug McCune). However, additions made to the framework in Flex 3 combined with new features of Flash Player 10 have made these cumbersome techniques redundant. It is now possible to provide this functionality directly from your Flex application in two simple steps.

The first step involves capturing the UI component's bitmap information. The Flex 3 API introduced the ImageSnapshot class specifically to simplify this process. The following line of code is sufficient to capture the image data:

ImageSnapshot.captureImage(myChart);

However, we are able to control the image capturing more precisely by using some of the method's optional parameters. These allow us to specify the target resolution in dots per inch and the image encoder to use (the Flex 3 API provides a PNGEncoder and a JPEGEncoder). So, for example, the following line of code would capture a chart as a PNG image at a resolution of 300dpi:

ImageSnapshot.captureImage(myChart, 300, new PNGEncoder());

Now that we have captured the image data all that remains is the second, and last, step: saving the image data to the user's file-system. Flash Player 10 introduced a number of changes to its security sandbox, principally the ability to programmatically prompt the userto save a file to their file-system. This is done using the FileReference class, as shown in the following lines of code:

var file:FileReference = new FileReference();
file.save(image.data, "chart.png");

So, putting the steps together results in a method along the lines of the following code snippet:

/**
 * Attempts to save the chart to the user's file-system.
 */
private function saveChart():void
{
    var image:ImageSnapshot = ImageSnapshot.captureImage(myChart, 300, new PNGEncoder());
    var file:FileReference = new FileReference();
    file.save(image.data, "chart.png");
}

The application below shows this code in action. The values in the data grid can be changed,with the changes reflected in the chart (just to show that I'm not cheating).

The source code is now available.