Exporting Visible Elements in Flash

Taking screenshots on your flash application is easy as flash supports it out of the box. I have written a simple exporter class to do this:

package com.utils
{
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.utils.ByteArray;
	
	import mx.core.UIComponent;
	import mx.graphics.codec.PNGEncoder;
	import mx.utils.Base64Encoder;

	public class ImageExport
	{
		static public function export(elements:Array):Array
		{
			var dataArray:Array = [];
			for each(var element:UIComponent in elements)
			{
				dataArray.push(_getBitmapData(element));
			}

			return dataArray
		}

		static protected function _getBitmapData(target:UIComponent):String
		{
			var bd:BitmapData = new BitmapData(target.width, target.height);
			var m:Matrix = new Matrix();
			bd.draw(target, m);
			
			var encoder:PNGEncoder = new PNGEncoder;
			var png:ByteArray = encoder.encode(bd);

			var be:Base64Encoder = new Base64Encoder();
			be.encodeBytes(png);
			return be.flush();
		}
	}
}

By calling the “export” function, it will return an array of encoded image strings and ready for you to json_encode it and then send to the server and allow user to download the images.

For PHP applications, you will need to json_decode the array and then base64_decode each of the image data before saving them into files or push to the browser content.

Happy Flex and PHPing.

Update ItemRenderer Dynamically

To update ItemRenderer dynamically in Flex is easy:

import mx.core.ClassFactory;
public function updateItemRenderer():void {

    this.myList.itemRenderer = new ClassFactory(YourItemRendererName);
}

YourItemRendererName needs to be a mxml component or ActionScript class component.

It is easy but if will be a headache if you don’t know the syntax.

AS3 – mx:List with ItemRenderer Scrolling Problem

ItemRenderer class instances in AS3 are re-used when rendering objects in mx:List.

For example, if you provide 500 elements to the list’s dataProvider, and only showing 10 rows in the list output, it will create around just over 10 instances of your ItemRenderer. And every time you scrolls the list, it will use the existing renderers to render those new elements in the list by simply calling the “set data” method. It will be up to you to update the state of the renderer yourself, otherwise you will expect very weird behaviours.

So you will need to do update your set data function:

override public function set data(value:Object):void {

    // need to remember to call this 
    super.data = value;
    /* then insert code here to update the state of the renderer */
}