Flex Image Resampling
May 6th, 2008While working on KatanaPG (picture uploader) I ran into a memory issue. Pictures, especially those taken with 6+MP cameras, are HUGE. When I was creating the thumbnails for them in the TileList was was simply resizing them. This kept all that 6MP of data in memory just loooked smaller. I needed to resample it at a lower resolution and then dispose of the original. I tried it multiple ways, first using an Image and setting the source and then the width and height. Then using a bitmap and scaleX and scaleY (as well as ImageSnapshop, but never go that to even work). After posting a question to flexcoders a very kind replier said: “Use bitmap.draw.” That method worked great. Below is a chart of the Flex Profile peak memory for each method. Pictures imported: 23 Photo Booth pictures 640 x 480 and about 150KB on disk each.
| Method | Peak Memory (KB) |
| image.width/height | 33,351 |
| bitmap.scaleX/scaleY | 61,837 |
| bitmap.draw | 7,107 |
I don’t know exactly why the first two methods take up almost as much memory as Firefox, but I am glad I managed to reduce the memory significantly. Now for he part you all have been waiting for, CODE. I used this code for a TileList.itemRenderer.
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100" height="100" initialize="init();" creationComplete="created();" dataChange="init()">
<mx:Script>
<![CDATA[
import mx.graphics.ImageSnapshot;
import mx.core.UIComponent;
private var _created:Boolean = false;
private function created():void
{
_created = true;
init();
}
private var contentLoader:Loader;
private function init():void
{
if(!_created)
return;
removeAllChildren();
contentLoader = new Loader();
contentLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadComplete);
contentLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorHandler);
var request:URLRequest = new URLRequest(data.url);
contentLoader.load(request);
}
//When image loaded, create scaled bitmap
private function LoadComplete(evt:Event):void
{
evt.stopImmediatePropagation();
var loader:Loader = Loader(evt.target.loader);
var image:Bitmap = Bitmap(loader.content);
var sxy:Number = (image.width > image.height)?(95/image.width):(95/image.height);
var scaleMatrix:Matrix = new Matrix();
scaleMatrix.scale(sxy,sxy);
var container:UIComponent = new UIComponent();
addChild(container);
var scaledImage:Bitmap = new Bitmap(new BitmapData(95,95,true,0));
scaledImage.bitmapData.draw(image,scaleMatrix);
container.addChild(scaledImage);
contentLoader = null;
image.bitmapData.dispose();
}
private function IOErrorHandler(evt:IOErrorEvent):void
{
trace("Error loading",data.url);
}
]]>
</mx:Script>
</mx:Canvas>

April 17th, 2010 at 2:35 pm
Thank you, this really helped a lot!