Embed types in ActionScript and memory usage

I’ve spent the last few days doing lots of fascinating ActionScript memory-tests – and hopefully I’ll post some of the results here if I get time – but while I have a quick moment I thought I’d share this finding which (while obvious now I think about it) caught me out.

The Embed meta-tag allows you to embed and access external files directly within your SWF, e.g.

[Embed(source = 'myImage.png')]
public static const MyImage:Class;

Flash seems to automagically detect the MIME-type of your embedded content (in this case, image/png), so that when you call new MyImage() the resulting object can be cast to a Bitmap.

You can, however, explicitly set a MIME-type for the embedded asset. If you’re crazy enough, you can do this:

[Embed(source = 'myImage.png',mimeType='application/octet-stream')]
public static const MyImage:Class;

This time calling new MyImage() will return an object of type ByteArray; in order to convert it into a bitmap, you will need to load the ByteArray into a Loader object.

Now, what caught me by surprise is the way in which the Flash compiler embeds the file myImage.png; I had foolishly assumed that the binary file would be embedded as-is, and then handled appropriately at run-time, but the compiler is a little smarter than that, and tries to handle the binary data according to its MIME-type. This is probably best demonstrated by example. In my test case, I embedded a large uncompressed PNG – the file was 1280×720 and came out at approx. 2.7MB.

With the first style of Embed (the “regular”), my compiled SWF was approx. 1.7MB or so in size, and when I ran it it decompressed to a similar size.

With the first style of Embed (the “byteArray”), my compiled SWF was a much smaller 800kB in size, but when I ran it it decompressed all the way back to 2.7MB.

I’m still trying to get my head around the implications of this (with a lot of help from Tish!) – it seems counter intuitive to me that the decompressed file sizes are so different, when presumably the “regular” version will have to be decompressed to a full 1280x720x4 (ARGB) bitmap data object. Any thoughts?