Thursday, December 4, 2008

Dynamically loading embedded images in AS3

Huge kudos for a post found on UltraShock that saved me today when I was on a crazy deadline to finish something:

I had recently completed a project that was built as a flash projector file. Originally the movie used external .jpg's that loaded at runtime, but to make it safer to distribute it was decided that all of the jpgs had to be embedded into the swf and loaded from there.

The actionscript stored all of the image names in an array and called them in sequence to load into a movieclip. To do this I just used a Loader() object. However when moving the assets into the swf I couldn't (quickly) find a simple way to load them dynamically anymore.

The first step was to turn each image into its own class with the filename as the class name -- so IMG_45.jpg was turned into a class (using the linkage panel) called IMG_45, etc. So far so good. But then we got stumped on how to load it dynamically. While I could have made them all movieclips, put them all on the timeline and called: this['IMG_45'] -- but that would have required that all 60 high res images be placed on the stage and probably killed performance.

In the end I had about 15 minutes to find a way to load the specific class when all I had was a the name of it -- as a string.

Anyway, some Googling found this brilliant function that solved it in 5 minutes instead:

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.getDefinitionByName;

var bitmapData:BitmapData = getBitmapData(myImg);
var bitmap:Bitmap = new Bitmap( bitmapData ); this.addChild(bitmap);

function getBitmapData( className:String ):BitmapData{
var obj:BitmapData;
var cls:Class = getClass( className );

try{
obj = new cls( 0, 0 );
}catch(err:Error){}

return obj;
}

function getClass( className:String ):Class{
return getDefinitionByName(className) as Class;
}

Awesome -- truly!!

No comments: