<mx:Flexing> A Paritosh Bisi’s Blog

On Rich Internet Applications, Adobe Flex, ActionScript, Web Technologies and more…

Archive for January, 2009

Taking snapshot from Flex applications

Posted by Paritosh Bisi on January 26, 2009

Recently I got a requirement to take snapshot from applications. I got the basic idea from the following blog…

http://www.mehtanirav.com/2007/09/10/taking-a-snapshot-of-flex-app-from-flex

Using Flex 3, taking a snapshot is quite easy, as Flex 3 provides us the built in APIs to take a snapshot. Using the ImageSnapshot class this can be achieved. Flex 3 also provides two image encoders JPEGEncoder and PNGEncoder.  Check the following link to see how to take snapshot using Flex 3.

But when you use the PNGEncoder or JPEGEncoder while processing the snapshot the UI freezes, because actionscript is single threaded – everything just runs on the browser’s main thread. To avoid the UI freeze we have to use a third party class called  JPEGAsyncEncoder check this link for more detils and codes.

Using Flex 2 also we can take snapshot. We have to use BitmapData, JPEGAsyncEncoder, ByteArray classes. For sending to server we need HTTPService, and server side scripting language like PHP. To download the converted JPEG image we need URLRequest and FileReference classes. We can take snapshot of any component which extends UIComponent class.

Sample Code [Take a snapshot of a canvas and save the JPEG image in server and download to local file system]

//FLEX Codes
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute”>

<mx:Script>
  <![CDATA[
   //Call this function to take snapshot
   //@param : pass the UIComponent (whose snapshot you want) as parameter
   public function takeSnapshot(target:UIComponent) :void {
        //Save bitmapdata
        var bd:BitmapData = new BitmapData(target.height, target.width);
        bd.draw(target);
        //Encode using JPEGAsyncEncoder
        var encoder:JPEGAsyncEncoder = new JPEGAsyncEncoder(80);
        encoder.PixelsPerIteration = 128;
        encoder.addEventListener(JPEGAsyncCompleteEvent.JPEGASYNC_COMPLETE, encodeDone);
        encoder.addEventListener(ProgressEvent.PROGRESS, encodeProg);
        encoder.encode(bd);
    }//End takeSnapshot

    //Encoding progress
    private function encodeProg(event: ProgressEvent):void {
    //Show progress using event.bytesLoaded and event.bytesTotal
    }

    //Encoding done event handler
    private function encodeDone(event: JPEGAsyncCompleteEvent):void {
      var ba:ByteArray = event.ImageData;
      //Encode using Base64Encoder
      var be:Base64Encoder = new Base64Encoder();
      be.encodeBytes(ba);
      var encodedData:String = be.flush();
      //Object to send to PHP
      var objSend:Object = new Object;
      objSend.encodedData = encodedData;
      //Send data to PHP
      writeData.send( objSend );
    }//End encodeDone

    //Result handler
    public function resultHandler( event: ResultEvent ):void {
      var res:String = event.result.toString();
      if(res == "SUCCESS"){
        Alert.show("Save file ?", "Encoder Test",
                   Alert.OK, this,
                   downloadFile, null, Alert.OK );
      }else {
        Alert.show("Error occured");
      }
    }//End resultHandler

    //Download code
    public function downloadFile(eventObj:CloseEvent):void {
        var fileUrl:String = http://localhost/encoder/test.jpeg;
        urlReq = new URLRequest(fileUrl);
        fileRef = new FileReference();
        //Add event listeners
        fileRef.addEventListener(ProgressEvent.PROGRESS, progEvent);
        //Start download   
      fileRef.download(urlReq);
      }
    }//End downloadFile

    //Download progress
    private function progEvent(evt: ProgressEvent):void{
      //show some progress using evt.bytesLoaded and evt.bytesTotal
    }//End progEvent

  ]]>
</mx:Script>
    <!–HTTPService to  talk with PHP–>
  <mx:HTTPService id=”writeData” url=” http://localhost/encoder/encode.php”
                  method=”POST” resultFormat=”text” result=”resultHandler(event)”/>
</mx:Application>

//PHP Script
//Encoder.php
//Saved at the location http://localhost/encoder/encode.php as per  the example

<?php

$encodedJPEGData = $_POST["encodedData"];
//Decode and save as a jpeg file
if ($encodedJPEGData != “”) {
   $binaryData = base64_decode($encodedJPEGData);
   file_put_contents(“test.jpeg”, $binaryData);
   $result = “SUCCESS”;
} else {
   //Some Error Occured
   $result = “ERROR”;
  }

//Send Result to Flex
echo $result;

?>

Hope this example will be useful for you.

Happy Flexing :-)

Posted in Flex Builder | Tagged: , , | 3 Comments »