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 user
to 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.


Hi Graham, great example! I’ve hit a bit of a stumble with importing the necessary packages. I get the following error;
1061: Call to a possibly undefined method ’save’ through a reference with static type flash.net:FileReference.
I’m obviously missing a part and I’m still very much learning Flex, could you provide a working sample code?
Thx
Hi. Your issue is likely to be due to your project configuration rather than the actual code. The save method on FileReference is only available from Flash Player 10 onwards so you must ensure that the project is being compiled for Flash Player 10. In Flex Builder you can do this by changing the “Require Flash Player version” number in the project’s properties -> Flex Compiler. Note that the Flex 3.2 and/or Flex Builder 3.0.2 updates are required to support Flash Player 10.
Let me know if you have any further problems.
Graham
Of all the searching I did to figure out how to get an image from the Flash Player to a user’s machine, no one else mentioned this method. This is exactly what we need for an application we’re using where we want to allow the user to save an image of a map they have been working on to send around for business purposes. I implemented your code in about 15 minutes, and it works flawlessly. Thanks for this post!
I am using Flex 3.3 and Flash Player 10 and still getting an error: 1061: Call to a possibly undefined method ’save’ through a reference with static type flash.net:FileReference.
I am using Eclipse as the IDE and building the project using ant script.
Can anyone please help me out as to what could be the issue?
When you say that you are using Flash Player 10, are you actually targeting it when you compile your application? This article explains how to target Flash Player 10 when using the command-line compiler.
Let me know if you have any further problems.
Graham
Can’t we save a chart image by avoiding the ’save’ dialog box? I mean to say, can’t we give an absolute url for the location to save the file.
The main reason this is not possible is due to security restrictions imposed by the Flash Player sandbox. If they were not in place, and it was possible to save a file straight to a user’s machine without the save dialog then it would be a very easy way to get malicious code onto a user’s machine. The save dialog forces the user to make an active decision to save something to their machine.
Hi Graham,
Which control you are using for displaying graph…..?
The problem is that i am using swfloader to load swf file in my application and now i want to take snap of that swf file.
So is that possible to take snap of swf file….?
Thanx in advance…
Regards,
Pradip Jadhav
Hi Pradip,
I’m using the standard Flex Charting components to display the chart.
I haven’t personally tried taking a snapshot of a swf file, but since SWFLoader extends DisplayObject, which implements IBitmapDrawable, I see no reason why using the code provided in the article but with myChart replaced by a reference to your SWFLoader instance wouldn’t work.
Graham
save works fine but after saving it shows grey and white color box and it is not opening in IE please any one help me
Could you provide a bit more detail, please? What shows a grey and white colour box and what is not opening in IE? Also, which version of IE?
Graham
same Chart what you are showing if i open in IE then it is opening and if I open my chart then it is not.
And at background it is showing white and grey box it is not showing white backrground
At runtime it is showing white Background but after saving it is giving me grey and white box at background
Can consult the view source for this application please??
The source code is available here.
Hi Graham,
Thanks for the point! I wonder if I can use this method on my web server for reporting issues. What I need is to create the chart and save its image automatically on server itself. So I can use this image file in crystal reports as a source..
Thanks for help!
Yeah, I see no immediate reason why an AIR application run server-side, possibly interfaced with using Merapi or similar, couldn’t be used in a setup as you describe.
Graham. Thanks for your tip about targeting Flash Player 10. I received that 1061 error, and you solved my issue. After a quick search, a lot of other people were having the same problem. They assumed that using the latest Flex API would take care of the issue. Thanks for the example, and thanks for the follow up!!!
This was a great article. Very much appreciated.
it works..
by the way, how could i save the image automatically after the page is loaded instead of button click
Hi Roy,
You could invoke the saveChart method shown above from the Application’s creationComplete event.
Regards,
Graham
i add creationComplete=”saveChart()” in the mx:application
and save chart under
private function saveChart():void
{
var image:ImageSnapshot = ImageSnapshot.captureImage(myChart, 300, new PNGEncoder(), true);
var file:FileReference = new FileReference();
file.save(image.data, “k:\chart.png”);
}
but it doesn’t work…any idea?
Could you provide a bit more information about what didn’t work, any errors, etc?
the image file does not saved in k: after the application is load completed. however, clicking on the button pop up a save as dialog as expected.
this is what i cam trying to do. when user open the page, it will automatically save a copy of chart in the server. is it possible?
Yes, this is possible. However, the technique I have outlined in this article is for client-side saving of the image, not server-side. To save an image server-side you need to send the image data back to the server using one of the many available techniques, e.g. POSTing to a servlet using an HTTPService or uploading using a RemoteObject.
thanks. i will look for another solution. thanks.
Hi Graham, thanks for the very useful piece of code
I have integrated it and seems working fine. But I have come across some complaints that the “Save Image” dialog box doesn’t shows the .png extension with some browser-platform combinations. For example, it works fine in both IE7 and Firefox 2 with Flash Player 10 in Windows XP. But when tested on IE7 and also IE8 in Windows Server 2008, it doesn’t shows the .png extension. Below is the function I’m using:
public function saveImage():void
{
var image:ImageSnapshot = ImageSnapshot.captureImage(ibdCurrentChart, 150, new PNGEncoder(), true);
var file:FileReference = new FileReference();
file.save(image.data, “image.png”);
}
Please suggest a solution.
Hi Jaymin,
I’m afraid that strikes me as being an issue somewhere between the Flash Player plug-in, the browser and the platform. At a guess, there will be no readily-available solution, I’m afraid. I do not have development access to a machine running Windows Server 2008 so I am unable to investigate further.
Graham
No probs Graham, Thanks for confirming.
I will investigate further and let you know if any success.
Jaymin