Workaround for: 9-slice scaling with bitmap images

Posted on May 25, 2009

1


9-slice scaling (see one of many articles here) has some peculiarities in Flash. First of all, it will only work for a graphic object. If you try to apply it to a bitmap image or an embedded movie clip, it fails like shown in the image below:

Picture 219

Everything is stretched out of proportions, where 9-slice scaling should preserve the corners and the borders. (See screen shots below to see the buildup.)

In the patterns I am building with the Flash RAD framework, the user can safely assume that 9-slice scaling will work for embedded bitmaps and movieclips as well. So I created a workaround using bitmap clipping.

Download

Download the Fla used for this test here. The code is embedded. It is created the same afternoon I wrote this article, not pretty, and some parts are open for improvement, but as a quick test and demo it suffices.

Parts

Below are three images showing the different stages:

The original clip

Picture 220

What it looks like when scaled in the Flash IDE: corners are distorted

Picture 219

The scaled result: correct properties

Picture 221

The corners are showing as expected: no scaling or distortion.

The distortion of the pattern inside is a logical result of the way 9-slice scaling is done. By relocating the slice-lines outside the bitmapped center, or by choosing a different background the bitmap will scale properly.

To prevent distortions at all, the shape as used above should be used as a mask applied on a background with the correct pattern. This will introduce other challenges as the multi-colored corners will all get the same texture as the background.

About 9-slice scaling and masking you can read in the previous post.

9-slice scaling: in the Flash IDE

Picture 186

Basis

Using the Bounding Rectangle of both the movie clip and the center of the 9-slice scaling area I define the dimensions of both the movieclip itself and the 9 slices I will use to scale.

Numbering them from 1 to 9, starting from the left top corner, the corners are numbers 1, 3, 7 and 9. These keep their width and height. The top and bottom sides (slice 2 and 8 ) are only stretched horizontally. The left and right side (slice 4 and 6) are stretched vertically. The middle is stretched both horizontally and vertically.

Bitmap clipping and use of sprites

Each slice is clipped from the original movie clip using a forced X/Y=0/0 and then placed into a separate Sprite. Each sprite is then put on the correct X/Y position with the correct width and length: related to the width and length of the stretched movie clip. This is not optimal in my opinion, but the most effective way for 9 slice scaling I found today.

Cleaning up / preventing memory leaks

For cleaning purposes I have created a separate function that scans the created objects, remove children and bitmap data if a child is of type Bitmap. This cleanup does not remove event listeners yet. It is advisable to catch events in persitant objects, to prevent objects having references still after removing them.

Limitations

The 9-slice scaling solution presented here is not suited for animations within the 9-sliced movie clip. To do that you will have to run an continuous update like done in the demo, which will eat about 50% to 70% of your CPU time.

Testing

Testing the code in an on-enterframe loop (where each enter frame the item is re-drawn) gives a drop from 60 frames to 30 frames per second (which is usable in normal circumstances as you will not constantly redraw your objects) and hardly any memory leak (the memory usage stayed stable when running continuously for more than 15 minutes).

Download the FLA (link at top of this article) to see for yourself.

Advertisements