Reputation: 145
I have a few contradicting misconceptions about how Flash handles image assets. I'm going to write them down here, please correct me where I'm wrong.
I have an embedded image
[Embed(source = "../../lib/images/myImage.png")]
public var embeddedImage:Class;
How do I use it in my app without using unreasonable amounts of operating memory?
I was going to do this:
var bData:BitmapData = (new embeddedImage() as Bitmap).bitmapData;
And from that point on use bData if I ever want to display this picture anywhere, ensuring that there is only one bitmapdata per image.
But what worries me is that embeddedImage still stays, doesn't it? There are basically two copies of this image in the operating memory, right?
What should I do instead? May be I should instantiate new embeddedImage() each time I want to use it? But that looks even worse, now I'm clearly instantiating a bunch of unneeded copies.
If I loaded the image using the Loader class I would end up with only one copy of the bitmapdata if I wanted to, provided GC did a good job clearing the loader after it was done.
Upvotes: 1
Views: 525
Reputation: 39466
The [Embed]
block embeds the image into the application. This doesn't use RAM*, it increases the size of the application itself (the .swf
or whatever format you export to).
When you use new EmbeddedImage()
, you create an instance of the embedded image. This instance is what consumes RAM. Each instance of that image will consume additional RAM.
When you access the bitmapData
property of that embedded image, it does not create a new instance or consume additional RAM, it refers to existing data which is already consuming RAM.
Because the BitmapData
is the data which represents an image, it is obviously the largest. Knowing this, we look at ways to use a single instance of BitmapData for any graphics we want to display. Depending on the display architecture you've opted to use, there are different ways to go about referring to that BitmapData when drawing multiple instances of the same image.
As an example, we have your instance of EmbeddedImage
created:
var embeddedImage:EmbeddedImage = new EmbeddedImage();
And we have a 'canvas', which is a single Bitmap
added to the stage:
var canvas:Bitmap = new Bitmap();
canvas.bitmapData = new BitmapData(500, 500, false, 0xFFFFFF);
addChild(canvas);
Using the method copyPixels()
, we can copy across a section of data from the embeddedImage
, to the canvas
without needing to make another instance of BitmapData
, which would consume RAM equivalent to the source for each time we want to draw the graphics. Example:
var drawPosition:Point = new Point();
var sourceRect:Rectangle = embeddedImage.bitmapData.rect;
// Draw the embeddedImage 50 times.
canvas.bitmapData.lock();
for(var i:int = 0; i < 50; i++)
{
canvas.bitmapData.copyPixels(embeddedImage.bitmapData, sourceRect, drawPosition);
drawPosition.x += 10;
}
canvas.bitmapData.unlock();
Upvotes: 2