Flex Paint - Flex Display Object to PNG
Flex allows you to easily create beautiful UIs. But what if you want to take a piece of the UI and save it as an image? Well, using Tinic’s AS3 PNG Encoder, Remote Object, and Flash’s BitmapData and ByteArray API it’s very easy. To show how this is done, I created a simple application called Flex Paint.
Flex Paint (requires Flash 9)
How it Works
We use the Flash drawing API to draw on a canvas. Then when the “Save Image” button is clicked we do a few simple things. First we create a new BitmapData object:
var bd:BitmapData = new BitmapData(canvas.width,canvas.height);
Then we copy canvas’ pixels onto the BitmapData object:
bd.draw(canvas);
Now we convert the BitmapData object to a ByteArray encoded as a PNG:
var ba:ByteArray = PNGEnc.encode(bd);
And then upload the PNG via Remote Object:
ro.doUpload(ba);
Then Remote Object just saves the file to the file system. If you would like to download the code for Flex Paint, you can find it on Source Forge. Let me know what you think. Thanks!
Flex, Java, Open Source, RIA

In case anybody else thinks for a moment that Save doesn’t work, note that there’s a popup on this page that you have to allow to see the PNG. Very nice!
fantastico!
I just posted this on a blog that linked here, but you can see Tinic’s encoding code in action on my Flex Derby project, Artmatic. http://matt-rix.com/fd/artmatic/
Check it out, let me know what you think… I’m not even sure it works with the Flash 9 release player :P It’s just a neat way to show how this stuff could be used.
hey James,
this probably isnt the place [where's the contact page?] but i have some issues when running this page on IE6.
The AS3 error doesnt make much sense to me, but i think it may be valueable to you.
take a look at the screenshot for details.
http://www.lfo-industries.com/flash9_kzzzt.png
cheers
Can you go here:
http://www.macromedia.com/software/flash/about/
And let me know what version you have?
Hello, I think this method is very interesting, but I have one question:
Where do you save java files? because flex file does not read java files.
I do not know where you save this component.
When I am running the application the follow error appears:
[URL=http://imageshack.us][IMG]http://img179.imageshack.us/img179/4372/errorflexpaintzg3.png[/IMG][/URL]
I am using coldfusion server, windows XP, flex builder 2.0 and data service 2.
How can I make the application run?
Thank you
the address image is:
http://img179.imageshack.us/img179/4372/errorflexpaintzg3.png
thank you
excellent script!!! i were looking for it since ages….
Hi James,
I’ve done some effort in that same area.
I used Open Lazslo, which is a Flex concurrent. I done a stress test (lots and lots of strokes) in both and my application add a better behavior, but yours seams to pick more point at the begin.
You can check my app at http://www.mainada.net/inputdraw
The advantage is that it integrates with javascript and directly with forms, so you can pass your drawing thru a form to your server, allowing to save drawing, process then and display them afterwards. which is nice to build drawing related webapps.
Hope you enjoy it.
Hi Tiago,
Cool app. Is it open source? I’d like to see how the code is different in OpenLaszlo, compared to Flex. Thanks.
-James
Hello James,
No, it is not open source. It’s a commercial product, but it has a similar free license for non-commercial projects, so that anyone can use it for their own projects (give at least something back :D).
Nevertheless, the code is very similar to a openlaszlo application. You can see their examples for fun.
Openlaszlo is also pretty great in some areas :)
Any more question, just drop me an email :) I’ll be plz to reply.
Take care.
- Tiago
Hi,
In case the paint area is too small to fit in the page,
the canvas use the scroll bar and some of the painting is out of the screen.
In this case the bitmap does not contain all the picture
How can I manage this problem?
Thanks,
Ronnie
Ronnie,
This should work fine. Try this example:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:VBox width="300" height="300"> <mx:Canvas id="c" width="500" height="500" backgroundColor="#ffffff"> <mx:Label left="0" top="0" text="top left"/> <mx:Label left="0" bottom="0" text="bottom left"/> <mx:Label right="0" top="0" text="top right"/> <mx:Label right="0" bottom="0" text="bottom right"/> </mx:Canvas> </mx:VBox> <mx:Canvas id="p" width="500" height="500"/> <mx:Button label="duplicate canvas"> <mx:click> import flash.display.BitmapData; var bd:BitmapData = new BitmapData(c.width,c.height); bd.draw(c); p.graphics.clear(); p.graphics.beginBitmapFill(bd); p.graphics.drawRect(0, 0, c.width, c.height); </mx:click> </mx:Button> </mx:Application>Hope that helps.
-James
1.) MyFlexApp.mxml (layout=”vertical”) has a docked ApplicationControlBar (height =”10%”) with 2 rows of icons/menus, each row with 3 sections. Is there a better layout strategy than nesting (and/or what is the performance hit from this level of nesting?)
AppControlBar
VBox
HBox
HBox - HBox - HBox
HBox
HBox - HBox - HBox
2.) Below the AppControlBar I have a (to enable drag/drop and resizing of flexmdi:MDIWindows) containing an MXML component consisting largely of layered pngs and jpgs (which make resizing “expensive”).
Would it be better to make either the background for the MDICanvas a swf or what is contained in the canvas a swf
in that http://www.cflex.net/showFileDetails.cfm?ObjectID=690 details how to communicate with an app loaded by SWFLoader or is this over complicating matters?
Experimentation to ensue on my part but suggestions would be much appreciated.
does this require java to be installed on the server?
i’m making an app that is going to be using XAMPP as the webserver locally, but they might not have java installed. they will have flash installed though.
thanks.josh.
Mike - You might want to take a look at the code for the Anvil project:
sf.net/projects/flexapps
(Anvil is in svn - no release yet)
I believe It has a lot of what you need already.
Josh - This particular examples does use Java on the server. But that could pretty easily be replaced by a number of other technologies.
great job! thanks!!
Hi James
This is awesome. Exactly what I’m looking for for my current project.
I cant find it on sourceforge. Please can you show me the location for the code?
Many thanks, and thank you for a great app! :)
Apologies for the last post. Coffee hadn’t kicked in yet.
I’ve found it. Thank you :)
Guys…
Does it work on PDA???
I tried it on windows mobile 5.0 and 6.0 device but it does not show up.
James, I saw your comment about the scrollbars but I don’t think that solves the issue completly. When there is a canvas that has scrollbars, do you know how to get that entire canvas (even the content that is not currently visible) to be copied into the BitmapData object? Here is a little sample that will show you that with scrollbars, only the visible section seems to be copied.
Hi Chris,
You just need to wrap your container with another container, like:
<mx:VBox width=”100%” height=”400″ horizontalScrollPolicy=”on” verticalScrollPolicy=”on”>
<mx:Canvas id=”c” backgroundColor=”#ffffff” horizontalScrollPolicy=”off” verticalScrollPolicy=”off”>
<mx:Label left=”0″ top=”0″ text=”top left”/>
<mx:Label text=”bottom left” y=”785″ x=”0″/>
<mx:Label text=”top right” y=”0″ x=”708″/>
<mx:Label text=”bottom right” y=”785″ x=”686″/>
</mx:Canvas>
</mx:VBox>
And use the Canvas’s width and height:
var bd:BitmapData = new BitmapData( c.width, c.height );
bd.draw(c);
try { p.removeChild(lbl); } catch( ex:Error ) {}
p.graphics.clear();
p.graphics.beginBitmapFill(bd);
p.graphics.drawRect(0, 0, c.width, c.height);
Let me know if that works.
-James
Hi Anenth,
You will have to use Adobe AIR if you want to get around the upload-then-download thing.
-James
i am developing a drawing application, is it possible to save the bitmap data in the canvas directly into the file system?
hi, Please give me a suggestion regarding:
if i add multiple image and an text ,it is possible to save whole.
thanks
Hi Ashu,
Yes, you certainly can do that. Anything on the screen can be saved as an image.
-James
Hi,
Im moderating your code to work with amfphp but am having a few problems with the save function:
private function doSave():void
{
var bd:BitmapData = new BitmapData(canvas.width,canvas.height);
bd.draw(canvas);
var ba:ByteArray = PNGEnc.encode(bd);
myservice.getOperation(’imagesave1′).send(ba);
}
Im trying to get the var ba to send to be uploaded but it doesnt work…
any help will greatly be appreciated
Hi Jeff,
I’m not familar with amfphp but can try to help you figure this out. Can you post your php code as well? Are you getting any errors?
-James
Hi James
Thank you for your excellent work. this has resolved my problem
i just used it the only problem is when click erase clears all the image can it modified so that it should erase just like paint eraser not the whole image.
Thanks
The PNGEnc.as works inconsistently for large sized canvas. I’m trying to load a background image to the canvas and then scribble on it and try saving the entire picture with annotation.
I am not able to save large sized canvas, about 800 X 600. Please help??
Hi Satish,
You might want to try and grab the latest version - which I think you can get here:
http://code.google.com/p/as3corelib/
If it still doesn’t work you might want to try the JPG encoder.
Let me know how it goes.
-James
Hi James,
Thanks a lot for your help. I downloaded the latest version, but the problem was actually in my servlet, i wasn’t doing a readFully() from the input stream, as a result i was writing incomplete data to my png file. Anyways, that is fixed.
Could you suggest me a book, or free link, which can help me learn flex with java in detail. I really need it. Thanks again.
Cheers,
Satish
Hi james,
I had another doubt, can i capture voice using a flex application, without using any third party server? The user has to speak something and my application has to capture whatever user said. Is it possible?
Thanks,
Satish
I was looking for an online drawing “thingy” to put on a website and I found yours. It was just what I needed. The only problem is: I don’t know shit about flash, flex or xml. So I downloaded the source code, but I don’t know how I have to upload it, I mean, which file in which map or if I have to make maps / packages. I know, really stupid question but maybe you could mail me or post me how to get it online properly. Cause, I tried it, and I got the flexpaint online but when I save I get errors like “destination not found” or something like that. So maybe I need to change something in the code or upload it correctly so it would work. Can you help me?
I don’t know nothing but maybe with your help I can get it online AND saving, thanks!
Hi Brightside,
You will probably want to download the source code from SourceForge and get Flex Builder (or Flex SDK) and LCDS Express. There is an ant built which should still work but I haven’t touched it in a while. I hope that helps.
-James
Hello James,
I’ve Flex Builder and ColdFusion 8 now. I got the resource files but I still don’t know what to do and how to do it. (I’m a total noob with Flex & Coldfusion)
You can always contact me with mail.
Thanks in advance!
I implemented your code and it runs but nothing is written to a file. (I am totally new to this stuff).
PNGEnc class is in PNGEnc.as.
I am trying to write a canvas image to a file c:\myPng.png
Please let me know what’s wrong. Thx a lot. Efi.
This is my code in Flex 3 :
a code in my previous comment was not shown, I add it here (canvas has some TextInput and VBox’es)
var bd:BitmapData = new BitmapData(Canvas.width,Canvas.height);
bd.draw(Canvas);
var ba:ByteArray = PNGEnc.encode(bd);
var ro:RemoteObject=new RemoteObject(”c:\myPng.png”);
ro.doUpload(ba);
Hi Efi,
You will need to manipulate the back-end Java class which the RemoteObject is hooked to if you want to change where the image is being saved. Also if you are in AIR you can save the image directly to the hard drive using the File APIs (as opposed to the RemoteObject API).
I hope that helps.
-James
Thanks. I am using Flex, is it possible to use AIR’s File APIs from Flex?
Do you mean use the AIR File API’s in the browser? If so, then no. AIR API’s can only be used on the desktop.
-James
Hi James,
Nice piece of code. When I set the alpha of the line to something less than one, I get the line with dots in it. What do I need to do to smooth the fill of the line out - I’m trying to approximate a highlighter pen.
Thanks.
Hi David,
Good question. I’m not totally sure but you might want to try using smoothing. I think you set that on the BitmapData but I’m not totally sure. Let me know what you find out.
-James
Can you pleasy send mie a zip-file, so that I can import the flexpaint application as a flex project, because the save button does´t work. I don´t know, what to do. Do I need the AS3 corelib - if yes, how to integrate? Thank you very much
Hi Björn,
You will need to get the code from SourceForge:
http://sourceforge.net/project/showfiles.php?group_id=174131&package_id=200814&release_id=439840
-James
can you please help me to work out this into jboss as local server. Thanks
Hi Karel,
Are you having problems running this on JBoss? I am running it on JBoss without any problems.
-James
Hi, everyone
anybody knows how to store DisplayObject to XML.
Thank you.
Hi Nishanth,
There isn’t any way to do this unfortunately.
-James
Hi, James
Thanks for your valuable response.
Hi, James
Is there any posibility to convert DisplayObject to ByteArray
(and again ByteArray to DisplayObject )?
Thank You.
Hi Shetty,
Unfortunately not currently. DisplayObjects can not be serialized or introspected.
Please file a feature request:
http://bugs.adobe.com
-James
Is there a way to only capture what was writen to the page? Not a screenshot of the image, only what was written to the page while I had the mousedown event envoked.
Hi Chuck,
In Flash you can capture anything (there is an exception to this but it probably won’t affect you). Is the page you are referring to being rendered by Flash or by HTML in the browser?
-James
Hello to you, James,
I want to test it on a website and, unfortunately, I have an error opening on a Flash Player 9 window when I want to save.
The error is :
“[RPC Fault faultString="[MessagingError message='Unknown destination 'UploadImage-ro'.']” faultCode=”InvokeFailed” faultDetail=”Couldn’t establish a connection to ‘UploadImage-ro’”]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::invoke()
at mx.rpc.remoting.mxml::Operation/http://www.adobe.com/2006/flex/mx/internal::invoke()
at mx.rpc.remoting::Operation/send()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.rpc.remoting.mxml::Operation/send()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.rpc::AbstractService/http://www.adobe.com/2006/actionscript/flash/proxy::callProperty()
at flexpaint/::doSave()
at flexpaint/___Button2_click()”
Is there a way to place file in flex?
Thank you so much
Jo
Hi Jo,
Did you get this on my website or did you try to set this up yourself?
-James