Developing Android Applications with Adobe AIR [108]
Use the BitmapData.draw method to render vector graphics into a bitmap. The first parameter, the only one required, is the source, bitmap, or vector. The following parameters are a Matrix, a ColorTransform, a blend mode, a Rectangle, and smoothing (only for the BitmapData source).
In this example, we are using the Matrix to scale the assets down to half their original size. Define the dimension of the BitmapData object used to store the pixels of the assets loaded and a Matrix:
import flash.display.BitmapData;
import flash.geom.Matrix;
const CELL_WIDTH:int = 50;
const CELL_HEIGHT:int = 100;
var composite:BitmapData = new BitmapData(CELL_WIDTH, CELL_HEIGHT, true, 0);
var matrix:Matrix = new Matrix(0.50, 0, 0, 0.50, 0, 0);
Create a Vector to store the path of the assets. The art must be loaded in the order it will be composited, as you would with layers in Flash or Photoshop:
var assets:Vector. assets[0] = PATH_SKIN_ASSET; assets[1] = PATH_HAIR_ASSET; assets[2] = PATH_SHIRT_ASSET; var counter:int = 0; Load one image at a time using a Loader object. A counter variable is used to traverse the Vector and load all the assets. Every time one is available in AIR, it is converted to a bitmap and added to BitmapData. Note that the draw method has the alpha argument set to true to preserve the area of the vector without pixels so that it remains transparent: import flash.display.Loader; import flash.net.URLRequest; import flash.events.Event; var loader:Loader = new Loader(); loader loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded); loading(); function loading():void { loader.load(new URLRequest(assets[counter])); } function onLoaded(event:Event):void { composite.draw(event.target.content, matrix); counter++; if (counter < assets.length) { loading(); } else { loader.contentLoaderInfo.removeEventListener( Event.COMPLETE, onLoaded); display(); } } Once all the assets are loaded and composited, create a Bitmap to render the image to the screen: import flash.display.Bitmap; function display():void { var bitmap:Bitmap = new Bitmap(composite); addChild(bitmap); } MovieClip with Multiple Frames Converting a MovieClip with vector art to a bitmap for better rendering is a good practice, but neither cacheAsBitmap nor cacheAsBitmapMatrix works for a MovieClip with multiple frames. If you cache the art on the first frame, as the play head moves, the old bitmap is discarded and the new frame needs to be rasterized. This is the case even if the animation is just a rotation or a position transformation. GPU rendering is not the technique to use for such a case. Instead, load your MovieClip without adding it to the display list. This time, we need to load a single .swf file and traverse its timeline to copy each frame. Load the external .swf file comprising 10 frames: var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete); loader.load(new URLRequest(PATH_TO_SWF)); Create a rectangle for the cell at a predefined size. Traverse the MovieClip, and use draw, as before, to copy the vector into a bitmap. Then use copyPixels to add the new pixels into another BitmapData that is the width of the total number of frames: function onLoadComplete(event:Event):void { event.target.removeEventListener(Event.COMPLETE, onLoaded); var mc:MovieClip = event.target.content as MovieClip; var totalWidth:int = mc.totalFrames*CELL_WIDTH; var complete:BitmapData = new BitmapData(totalWidth, CELL_HEIGHT, true, 0); var rectangle:Rectangle = new Rectangle(0, 0, CELL_WIDTH, CELL_HEIGHT); var bounds:int = mc.totalFrames; for (var i:int = 0; i < bounds; i++) { mc.gotoAndStop(i+1); var frame:BitmapData = new BitmapData(CELL_WIDTH, CELL_HEIGHT, true, 0); frame.draw(mc, scaleMatrix); complete.copyPixels(image, rectangle,
Art production may require the use of a movie clip with multiple frames. This is a familiar workflow for many designers while also having the flexibility of being resizable.