This weekend I was doing some research about capturing ‘screen shots’ of a Flex application, or even specific UI components, and passing the ‘image’ back to the server for processing.
While there are a few ways to do this, I am going to discuss the ‘easiest’. Using the JPGEncoder class packaged as part of the AS3 CoreLib on Google Code. Using this class to encode the data on the client side means that very little needs to be done server side to save the data as an image.
Its fairly easy to use this encoder to create binary data and pass it to CF. I have set up an example here. If you enter some text into the text area inside the panel and click ‘Send Image’, Flex will create a JPG of the panel and send it off to CF.
Here is a look at some of the code, you can also view the source from the Flex application.
First, I import the JPGEncoder class. I store a lot of AS libraries and components in one location and add them to the ‘source path’ of my application.
import com.adobe.images.JPGEncoder;
Next, I create a method that converts a UI component into BitmapData.
private
function getBitmapData(target: UIComponent): BitmapData {
var bitmapData: BitmapData = new BitmapData(target.width, target.height);
var matrix: Matrix = new Matrix();
bitmapData.draw(target, matrix);
return bitmapData;
}
As you can see, this method can take any UI element as an argument. This method returns the bitmap data of the UI element that was passed in.
Next, I create a method that handles calling the above method, and then sends the result to ColdFusion:
private
function sendImage(target: UIComponent): void {
var bitmapData: BitmapData = getBitmapData(target);
var jpgEncoder: JPGEncoder = new JPGEncoder(90);
var imgData: ByteArray = jpgEncoder.encode(bitmapData);
imageService.saveImage(imgData);
}
This method also takes any UI element and uses it when calling getBitmapData(). It also creates an instance of the JPGEncoder class. The ‘90‘ that is passed into the constructor of JPGEncoder is the ‘quality’ of the resulting JPG.
Next we need to create a<mx:remoteObject> to talk to ColdFusion.
<mx:RemoteObject destination="ColdFusion" id="imageService" showBusyCursor="true" source="path.to.cfc">
<mx:method name="saveImage" result="onResult(event)"/>
</mx:RemoteObject>
The CFC itself is very simple, it contains 1 method whose only argument is the binary data that is our image.
<cfcomponent displayname="Image Service" name="Image Service" output="false">
<cffunction access="remote" name="saveImage" output="false" returntype="any">
<cfargument name="data" required="true" type="binary"/>
<cffile action="write" file="c:Tempflex_image.jpg" output="#arguments.data#"/>
</cffunction>
</cfcomponent>
You will see that inside the method all we do is a <cffile> to write the data to a file.
Lastly, we need some code that will fire off this entire event inside our Flex application.
<mx:Panel height="400" id="panel" layout="absolute" title="My Title" width="400">
<mx:TextArea bottom="5" left="5" right="5" top="5"/>
</mx:Panel>
<mx:Text text="Enter some text in the text area above and click 'Send Image'"/>
<mx:Button click="sendImage(panel)" label="Send Image"/>
In my online example I have other code that will open a new browser window and show you the image you just captured. You can view the source by right-clicking the application and selecting ‘View Source’.
Using this technique, you can do a screen shot of your entire application, or just individual UI components.