Posts Tagged ‘BitmapData’

Flash Image Sequence Memory Issues

I guess most of you are aware of the Bitmap memory leak in Flash Player and that you have to call the BitmapData.dispose() method to actually free the memory. But what to do if you don’t have a reference to the BitmapData?

That’s essentially a problem when dealing with MovieClips with an image sequence on its timeline. After adding the MovieClip to the stage and accessing each frame the complete sequence is in memory and removing it from the stage again doesn’t free any of this memory. Obviously the single frames are getting converted to Shapes with bitmap fill internally, so you don’t have a Bitmap instance for each frame and therefore you can’t dispose the frames after showing the sequence.

Sequence Example (the swf has no preloader, so you’ll probably have to wait a little bit)
Sequence Example Source (9MB, Flash CS3)

The only solution for this problem is to load the sequence as an external swf and call the unload method of your Loader instance when you don’t need the sequence anymore and want to free the memory. Alternatively you could load the single jpg frames individually, create your sequence programmatically and use BitmapData.dispose() afterwards.

BitmapData.draw() is limited to 4096px

Thanks to Jens I figured out another limitation in the BitmapData class. It’s actually buried in the draw() method which doesn’t copy any pixels to the BitmapData object whose target x-/y-position is greater than 4096px (0×1000). You don’t get any error just the pixels won’t be copied. This behavior is the same in FlashPlayer 9 and 10 and of course AIR 1.0 – 1.5.
Actually this is no problem for the regular use of BitmapData in FP9 because the BitmapData size is limited to 2880x2880px but using my BitmapDataUnlimited Class and trying to snapshot a Sprite wider or higher than 4096px won’t end up in your desired result.
As you probably know Adobe changed the BitmapData limit in FP10 to a more flexible one, so you are not limited by a specific size anymore but a maximum pixel count of 16,777,215. This means that you can have a BitmapData up to 8191x2048px without using BitmapDataUnlimited but interestingly you can’t draw a Sprite with the same size to this BitmapData object. I think Adobe forgot about their own secret, undocumented »feature«.

example

Sprite: w=8191, h=2048

FP10 BitmapData: w=8191, h=2048 with snapshot of the Sprite

workaround

A workaround for that problem would be to draw everything directly to the BitmapData or if you have to snapshot a Sprite greater than 4096px you could draw it to 4096px BitmapData chunks and copy them to the huge BitmapData afterwards using copyPixels().

Update December 14th, 2008

I added a draw method to the BitmapDataUnlimited class to bypass the 4096px limit.

beyond 8191px

The limit of 8191px (or 0x1FFF in hex) is probably less known but it’s actually the maximum size for DisplayObjects. If your objects width or height is greater than this limit it won’t get rendered anymore.
I mentioned in an earlier post that you can create even bigger DisplayObjects with BitmapDataUnlimited. This is still true even though there are a few restrictions.

I put together a small demo to show you my results:
http://projects.formatlos.de/spiking/1fff/
click inside the window to gain Keyboard focus,
use your arrow keys to move the container 1px (hold shift: 10px, hold alt: 100px)

add via Bitmap, no scale

...
// hugeBitmapData: w=9000, h=10
container.addChild(new Bitmap(hugeBitmapData));
...

This is probably the most convenient way to add a BitmapData to the stage. As you can see in the demo this works perfectly.

add via Bitmap, scale -> width=8191

...
// hugeBitmapData: w=9000, h=10
container.addChild(new Bitmap(hugeBitmapData));
container.width = 8191;
...

The same as above, just scaling down the Sprite to 8191px. It seems to work but moving the container some px to the right shows a strange rendering behaviour.

add via Bitmap, scale -> width=8192

...
// hugeBitmapData: w=9000, h=10
container.addChild(new Bitmap(hugeBitmapData));
container.width = 8192;
...

This time scaling down the Sprite to 8192px which is 1px above the limit and therefore doesn’t get rendered. moving the container some px to the right shows the same strange rendering behaviour again.
If you move the container off the stage (to the left) the exact amout of px exceeding the limit, in our case 1px, the Sprite gets rendered again. I presume Flash Player calculates the significant width/height based on the DisplayObjects bounds relating to the stage and by moving the Sprite off the stage the width/height which has to be rendered is smaller than the limit.

add via graphics, scale -> width=8192

...
// hugeBitmapData: w=9000, h=10
container.graphics.beginBitmapFill(hugeBitmapData);
container.graphics.drawRect(0,0,hugeBitmapData.rect.width,hugeBitmapData.rect.height);
container.graphics.endFill();
container.width = 8192;
...

Apparently there is no such limit for the Graphics Object therefore you can use beginBitmapFill and drawRect to draw your BitmapData to a Sprite and scale it afterwards.


Download Demo Source

No real masking with BitmapDataUnlimited

It would have been too cool if there weren’t any limits with BitmapDataUnlimited, but unfortunately I have to tell you that there are limits.
For a recent project I needed an alpha mask greater than 2880px. The problem is that applying an alpha mask requires the cacheAsBitmap property of both the mask and the masked Sprite to be true, but for DisplayObjects greater than 2880px you can’t activate Bitmap caching or at least it’s ignored.

I have tried to apply a filter to the Sprites which normally forces Bitmap caching but it didn’t work out either. The next idea was to use BlendMode.ALPHA instead of a real mask but still no success. So the only working solution for the moment is to render a Bitmap and place it in front of the other layers. very oldschool but it works.

If you know a better solution please let me know.

BitmapDataUnlimited

I think everybody who has worked with BitmapData in ActionScript knows about the 2880 pixel limitation of the Flash Player. Fortunately Adobe decided to rise this limit in Flash Player 10, I think something about 4000px.

Last week I visited the Flash Forum Conference in Cologne which was btw. great. A lot of inspiration and cool stuff. In his presentation Mario Klingemann talked about »Andre Michelle’s Huge Bitmap hack«. Read more »

About

Martin Rädlinger is an Interactive Developer & Designer. He specializes in interactive coding predominantly with ActionScript, but every new challenge is welcome. If you like his work feel free to get in touch with him. At the moment he's available for freelance work.

Contact

Martin Rädlinger
mail: mr [at] formatlos.de
web: www.formatlos.de
xing: Martin Rädlinger
linkedin: Martin Rädlinger
skype: martinraedlinger