Embedding assets with mxmlc as flash.display.BitmapData

Posted on March 22, 2010 | 5 comments

I have been playing with optimization techniques for building applications targeted for constrained devices. While at 360Flex and talking about some of the memory size issues around getting bitmap assets into ActionScript applications Brian Diette provide a tidbit which was quite useful.

In my original finding and understanding of getting assets into a SWF there was two ways. Using the [Embed] metadata with mxmlc to embed assets directly into class properties, see below:

[javascript]
public function MAssetEmbed()
{
var s:DisplayObject = new asset();
s.x = 50;
s.rotation = 30;
addChild(s);
}

[Embed(source="assets/Spinner.png")]
private var asset:Class;
[/javascript]

The result is a SWF with the asset class which inherits mx.core.BitmapAsset. Well, mx.core is a Flex class and this means it pulls in a bunch of other dependencies. This is important for Flex applications using assets as they can be attached to the Flex display list which requires UIComponent. But for pure optimization the goal is to figure out the method for embedding the bitmap asset into the application in the smallest size possible. This led me to the second approach which is to use Flash CS Professional to export the bitmap into a SWC. In Flash CS Professional you import the image into the .fla file’s Library. Then right click on the graphic (not MovieClip) in the library and click on Properties. Check the “Export …” checkboxes, give it a Class name, and then set the base class to flash.display.BitmapData, see the image below:

Flash CS Pro Export Symbol

Then you need to set the .fla files Publish Settings to export as a SWC. This is done by going to the Publish Settings -> Flash tab, and then check the “Export as SWC” checkbox 2/3 down the dialog. Once the SWC is exporting to a known location, copy the SWC into the ActionScript’s library path (ie: libs folder in Flash Builder projects). The bitmap asset is then accessed by declaring a instance with the export class name you set above, see the code below:

[javascript]
public function MAssetSWC()
{
var b:BitmapData = new SpinnerBD(0, 0);
var s:Bitmap = new Bitmap(b);
s.x = 50;
s.rotation = 30;
addChild(s);
}
[/javascript]

The SpinnerBD class in this case only inherits flash.display.BitmapData and doesn’t bring in other class dependencies like mx.core.BitmapAsset. Ok so it would be really nice to do this same thing with out going through all the Flash CS Professional steps. There is a way, thanks to the tip from Brian. He brought to my attention that the [Embed] tag when applied to a class makes the embedded asset take on the class inheritance structure. What this means I can take a custom class, say SpinnerEmbedBD, that inherits flash.display.BitmapData and then apply the same [Embed] metadata as I did for the property. This class looks like this:

[javascript]
package examples
{
import flash.display.BitmapData;

[Embed(source="/assets/Spinner.png")]
public class SpinnerEmbedBD extends BitmapData
{
public function SpinnerEmbedBD(width:int, height:int, transparent:Boolean=true, fillColor:uint=4.294967295E9)
{
super(width, height, transparent, fillColor);
}
}
}
[/javascript]

Now we can use this class directly in our ActionScript project by referencing SpinnerEmbedBD or compile it into a SWC library, in the end its the same code to use in the application just declare the new class. Since the class inherits flash.display.BitmapData its ready to attach to the display list in the smallest form. The code looks just like the MAssetSWC code:

[javascript]
public function MAssetEmbedBD()
{
var b:BitmapData = new SpinnerEmbedBD(0, 0);
var s:Bitmap = new Bitmap(b);
s.x = 50;
s.rotation = 30;
addChild(s);
}
[/javascript]

This is actually quite nice, for example it could be coupled with an ANT script that could take a bunch of images in a folder and spit out a SWC library with all their image names as class names available for the application to reference. No more updating one asset class with bunch of [Embed] properties.

  • http://tahirahmed.wordpress.com Tahir Ahmed

    Aahh! This is the kind of solution I was looking for 5-6 days ago when I was trying to [Embed] some image assets. FlashDevelop kept on throwing errors of not finding mx.core.BitmapAsset class for which, in the end, I had to point FlashDevelop to use framework.swc and import this unnecessary extra classes.

    P.S. I just didn’t think of exporting a Bitmap using Flash CS4 IDE at all which could’ve easily worked in my case; stupid me.

    - Tahir.

  • http://blog.martian-arts.org y_nk

    why not using graphics.beginBitmapFill to let your clip be interactive too ? What do you think about it ?

    package examples
    {
    static public function prepare(bmd:BitmapData):Sprite
    {
    var s:Sprite = new Sprite;
    s.graphics.beginBitmapFill(bmd, null, false, true);
    s.graphics.drawRect(0, 0, bmd.width, bmd.height);
    s.graphics.endFill();

    return s;
    }

    [Embed(source="/assets/Spinner.png")] private var asset:Class;

    public class Main()
    {
    public function Main()
    {
    addChild(prepare(new asset());
    }
    }
    }

    • http://www.renaun.com Renaun Erickson

      I actually do this for interactivity but the point of this post was how to get the BitmapData into the ActionScript project in the smallest form. Your example still will bring in the “asset” class as mx.core.BitmapAsset which is heavier then flash.display.BitmapData.

  • http://nascode.com Inas Luthfi

    I have posted similar post like this, including useful links to other blogs discussing MXMLC asset embedding. It is at http://nascode.com/2010/02/01/embedding-asset-at-compile-time-in-pure-as3-project/.

    Sorry if my english is not too good :(

  • http://www.garthdb.com Garth Braithwaite

    Awesome. I’m digging the rebrand by the way.