Flex Image Resampling

May 6th, 2008

While 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>

Tags: ,

One Response to “Flex Image Resampling”

  1. Morningstar Says:

    Thank you, this really helped a lot!

Leave a Reply