AS3 BitmapData AMF solution using IExternalizable

Posted on September 12, 2009

0


Using bitmaps in an AS3 remoting environment isn’t that easy. If I’m getting it right, the problem is that the BitmapData object needs constructor parameters, wich isn’t combinable with the handy [RemoteClass(alias= ] method of invoking the objects when streaming data into a ByteArray.

A walkaround is to wrap the BitmapData into a custom class implementing the IExternalizable interface. This interface forces the writing and reading of data through methods where the serialization can be taken care of.
In the example below (a renamed copy of this class, thank you Greg! – unfortunately I couldn’t find your lastname…), the bitmap data storage is done through encoding/decoding as png data. Loading is then performed via a Loader object.

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.utils.ByteArray;
    import flash.utils.IDataInput;
    import flash.utils.IDataOutput;
    import flash.utils.IExternalizable;
    import mx.graphics.codec.PNGEncoder;

    [RemoteClass(name="ExtBitmap")]
    public class ExtBitmap implements IExternalizable
    {
        public var imageData:BitmapData;

        protected var loader:Loader;

        public function ExtBitmap(){
            loader = new Loader();
            loader.contentLoaderInfo.addEventListener(
                   Event.COMPLETE, handleBytesLoaded);
        }

        public function handleBytesLoaded(event:Event):void{
            trace('handleBytesLoaded');
            imageData = Bitmap(loader.content).bitmapData;
        }

        public function writeExternal(out:IDataOutput):void{
            trace('writeExternal');
            var encoder:PNGEncoder = new PNGEncoder();
            var bytes:ByteArray = encoder.encode(imageData);
            bytes.position = 0; // may not be necessary
            out.writeDouble(bytes.length);
            out.writeBytes(bytes);
        }

        public function readExternal(input:IDataInput):void{
            trace('readExternal');
            var length:Number = input.readDouble();
            var pngData:ByteArray = new ByteArray();
            input.readBytes(pngData,0,length);
            loader.loadBytes(pngData);
        }
    }
}

Let’s hope that this kind of wierdness can be forgotten in AS4…

Tagged: , ,
Posted in: Actionscript 3