Entrepreneur Geek

Nirav Mehta on life, technology and future

Taking a snapshot of Flex app, from Flex!

with 15 comments

On a recent Flex project, we needed to take a snapshot of what's shown on the screen and save it as an image. I had seen somewhere that this was possible, but couldn't locate how exactly it was to be done. Turns out it's very easy to do such a screen capture / screen grab using Flex.

The essential steps are:

  • Create a new BitmapData object.
  • Copy the target component's pixel data into BitmapData object.
  • Convert the BitmapData object to a PNG encoded ByteArray (using the PNGEnc library)
  • Convert the ByteArray to a Base64Encoded string so that we can send the data safely to the backend.
  • On the backend (PHP via WebORB in our case), decode the data and write it to a file.

Most of the piece come from two places. James Ward has described this technique in his Flex Paint sample. And Tinic Uro has written the PNG Encoder library. Let's see the code now.

Here's the Flex Code:

XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  3. <mx:Script>
  4. <![CDATA[
  5. import mx.utils.Base64Encoder;
  6. import mx.rpc.events.ResultEvent;
  7. import mx.utils.ObjectUtil;
  8. import mx.controls.Alert;
  9. import mx.rpc.events.FaultEvent;
  10. import mx.core.UIComponent;
  11.  
  12. public function onResult(event:ResultEvent) :void
  13. {
  14. Alert.show(ObjectUtil.toString(event.result));
  15. }
  16.  
  17. public function onFault(event:FaultEvent) :void
  18. {
  19. Alert.show("Got error: "+event.message);
  20. }
  21.  
  22. public function takeSnapshot(target:UIComponent) :void
  23. {
  24. var bd:BitmapData = new BitmapData(target.width,target.height);
  25. bd.draw(target);
  26. var ba:ByteArray = PNGEnc.encode(bd);
  27. var be:Base64Encoder = new Base64Encoder();
  28. be.encodeBytes(ba);
  29. var encodedData:String = be.flush();
  30. ro.saveImage(encodedData);
  31. }
  32. ]]>
  33. </mx:Script>
  34.  
  35. <mx:Button click="takeSnapshot(targetPanel)" label="Save Image" x="10" y="100"/>
  36.  
  37. <mx :P anel id="targetPanel">
  38. <mx:Canvas backgroundColor="#EEEEEE">
  39. <mx:Label text="Hello World" />
  40. </mx:Canvas>
  41. </mx :P anel>
  42.  
  43. <mx:RemoteObject id="ro" destination="serviceEndpoint" result="onResult(event)" fault="onFault(event)"/>
  44. </mx:Application>

We use WebORB for backend connectivity. Assuming you have the connection in place, we can simply call a method passing the base 64 encoded string and save it on the server. If you don't have RemoteObject / Web Service, you can also use an HTTP POST. The reason to use Base 64 encoding is to get a string we can safely pass around, instead of a byte array.

Here's the PHP side of the code:

PHP:
  1. public function saveImage($encodedPNGData)
  2. {
  3. if ($encodedPNGData != "")
  4. {
  5. $binaryData = base64_decode($encodedPNGData);
  6. $file = "assets/images/something.png";
  7. file_put_contents($file, $binaryData);
  8. return $file;
  9. }
  10. return null;
  11. }

I could resize and do anything else with the image on the PHP side now.

Hope you find some creative use of this :)

Related posts:

  1. Scrolling with mouse wheel in Flex application – even on Mac By default Flex components do not scroll as you scroll...
  2. Auto Complete Text Component for Flex Was looking for ways to skin a combobox and found...
  3. Intelligent Time Duration / Estimate Slider in Flex (inspired from The Hit List) I wrote yesterday that I am working on a time...

Written by Nirav

September 10th, 2007 at 2:09 pm

Posted in Flex & Flash, PHP

 

15 Responses to 'Taking a snapshot of Flex app, from Flex!'

Subscribe to comments with RSS or TrackBack to 'Taking a snapshot of Flex app, from Flex!'.

  1. Nice!

    Currently i am concentrating on OpenLaszlo development at the moment, so i probably won’t be able to make use of this code. Still, it is possible to access flash api’s from OpenLaszlo, so maybe i can make use of that rather interesting ByteArray class to at least handle binary data.

    James Urquhart

    10 Sep 07 at 4:20 pm

  2. Hello Sir

    This is a cool stuff

    In fact it helped me but can you clarify this

    PNGEnc.encode

    what it does and is it a class[could not locate it in the help]

    vinay

    10 Sep 07 at 4:47 pm

  3. Oops

    I got the answer of my question

    U have already mentioned it

    Reading Skills have gone down :)

    vinay

    11 Sep 07 at 11:07 am

  4. Hi!

    You mention uploading the file could work with HTTP POST. How would that work?
    I don’t have flex data services nor WebORB installed.

    grtz!

    maxim

    15 Sep 07 at 7:53 pm

  5. Hi Maxim,

    Make an HTTP Service and pass the base 64 encoded string as a parameter.

    For more, a look at HTTPService Live Docs, Adobe article on using Flex with PHP and Mike Potter’s similar article.

    HTH.

    :Nirav

    Nirav

    16 Sep 07 at 9:56 am

  6. Wicked,

    Thanks Nirav.

    Implemented it into http://www.redesignme.org

    greetings!

    Maxim

    18 Sep 07 at 4:12 am

  7. I just came across this, and I was still having trouble with getting the HTTP Service to work can anyone help me out?

    JmfD

    22 Oct 08 at 7:32 pm

  8. @JmfD: What are the troubles you are having with HTTP Service to get this to work? Are you getting POST request on server? Can you dump everything that’s coming in POST and see what you get?

    Nirav

    23 Oct 08 at 1:11 pm

  9. I’m pretty new to Flex and I don’t know how to pass the base 64 encode string as a parameter. When I’m trying to change it to a HTTP Post I get an error about how saveImage is undefined.

    JmfD

    23 Oct 08 at 7:15 pm

  10. [...] Create Bitmap data from Flex UI and bounce off a server page e.g. see http://www.mehtanirav.com/2007/09/10/taking-a-snapshot-of-flex-app-from-flex [...]

  11. Hi i am newbie to flex,
    When i try to integrate this code into flex applilcation, i got the error “Severity and Description Path Resource Location Creation Time Id
    1180: Call to a possibly undefined method shr. project/src/components PNGEnc.as line 39 1244012791890 122
    ” could you please help me out this.
    thanks in advance,
    Mervin Thomas

    Mervin Thomas

    3 Jun 09 at 12:40 pm

  12. [...] flex we can use ImageSnapShot to snapshot some pictures from a flex component container.(reference:Taking a snapshot of Flex app, from Flex!)but as much as ever? fixed component size, fixed component position? And now.I had seen somewhere [...]

  13. How can I use this code to take capture user screen.
    Like print screen button do it?

    Thanks

    Khurram

    6 Oct 09 at 7:01 pm

  14. It’s not possible to capture desktop screen from Flex yet. You would need a software running on the desktop to take screenshot. Last I checked, it’s not even possible with AIR. But is a feature that may come in future.

    Nirav

    9 Oct 09 at 2:18 pm

Leave a Reply