Introducing the Scale9Bitmap class

The Scale9Bitmap class applies a scale9Grid to a Bitmap. It takes advantage of a technique I used for DestroyTwitter’s window drop shadow, scaling nine Bitmap instances. When developing the MAX Companion, I tried Didier Brun’s ScaleBitmap class, but discovered a costly memory leak in which it instantiates a new BitmapData instance with every resize call. This wouldn’t be a big deal for a once-and-done resize, but as a window drop shadow, memory skyrockets.
I decided to start from scratch and develop a class that is super fast and slim as can be. The Bitmaps are only updated when the BitmapData is set. After that, the only process that takes place is the resizing of each Bitmap—no BitmapData manipulation needed. Setup requires a single method to set the BitmapData and the Rectangle that indicates the stretchable portion of the Bitmap. BitmapData can be changed on the fly and there is a scale property that sets both scaleX and scaleY.
The source code is on GitHub, so feel free to give it a whirl.
Very nice! I really like scale9 for elements that dynamically resize, like buttons. This looks like a really handy and efficient way of getting the same effect for bitmaps. Thanks!
@Jackson — Thanks! I’ve been wanting to write this one for a while now.
Looks good. I’ve been using original bytearray.org ScaleBitmap, I even made some improvements to it. But you’re right, it becomes too lazy if overused. I’ll try your class now, let’s see how it improves speed of my components (exactly where it’s overused) :]
Thanks man.
@Vaclav — Let me know how it performs.
Everything works very well. Except one thing:
In case scale9Grid.y == 0 (I guess it applies to x as well), then:
@338 bitmap.bitmapData = new BitmapData(rect.width, rect.height);
fails with invalid BitmapData. Well because rect.height is zero.
Now I need to figure out how to use your class with scale3 rectangle, I use it more often than scale9 – for example it’s very useful for input bar backgrounds, where you need to scale just horizontally. Time to fork? :]
Maybe it’s better not to be lazy. I’ll revisit my slicing policy to have scale9 everywhere.
Hm, maybe it’s too late and my brain doesn’t work anymore, but I think I found a bug:
When setup() is called with the same BitmapData as before (e.g. setup() called twice for any reason), reference to this BitmapData is invalidated by using _bitmapData.dispose():
@192 if (_bitmapData) _bitmapData.dispose();
When this line is executed, not just _bitmapData, but even bitmapData (method parameter, a new (actually old) BitmapData) are invalid and valid() throws an error.
For this reason I changed:
@192 if (_bitmapData && _bitmapData != bitmapData) _bitmapData.dispose();
@251 if (_bitmapData && _bitmapData != bitmapData) _bitmapData.dispose();
I am not sure if I broke anything, but it works so far.
You can see it here: http://github.com/vancura/atollon. End of spamming, good night. Your blog is not an IM :]