Manipulating a loaded image with BitmapData in AS3

It’s very useful to work with external files and load them in Flash, using a preloader for example or adding some nice effects. Let’s see how to manipulate a loaded image with BitmapData in AS3 using few lines of code.


Preview the final result

Loading an image

Probably you know already how to load an image in Flash, using AS3. Create a new ActionScript file Main.as and first declare variables for loader:

[as3]
private var loader:Loader;
private var imgPath:String = "img.gif";
[/as3]

Then the constructor and init functions will be:

[as3]
public function Main() {
if (stage) init()
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);

loader = new Loader();
loader.load(new URLRequest(imgPath));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
}
[/as3]

Once the image is loaded, the “onComplete” function will be triggered:

[as3]
private function onComplete(e:Event):void
{
splitBitmap(e.target.loader.content.bitmapData, 3, 5);
}
[/as3]

I’m trying to create an effect like an image divided in many thumbs that regroups random. Create a function splitBitmap that receives 3 parameters: first is the loader’s content as bitmap, second and third one represents the columns and rows.

[as3]
private function splitBitmap(bitmapSource:BitmapData, columns:int, rows:int):void
{ }
[/as3]

It’s time to declare new variables for Bitmap and BitmapData:

[as3]
private var bitmapData:BitmapData;
private var bitmap:Bitmap;
private var space:int = 0;
[/as3]

Focus now on splitBitmap function. We need variables for Bitmap info, like width or height:

[as3]
var bitmapWidth:int = bitmapSource.width;
var bitmapHeight:int = bitmapSource.height;

var thumbWidth:Number = Math.round(bitmapWidth / columns);
var thumbHeight:Number = Math.round(bitmapHeight / rows);
[/as3]

After we know what size does Bitmap have, create a BitmapData object as model for each thumbs:

[as3]
bitmapData = new BitmapData(bitmapWidth, bitmapHeight);
bitmapData.draw(bitmapSource);
[/as3]

From now on it’s simple, create a for statement for X and Y position and add thumbs according to them:

[as3]
for (var i = 0; i < columns; i++) {
for (var j:int = 0; j < rows; j++)
{

}
}
[/as3]


Putting all together

Inside of this statement create a new BitmapData for each thumb, use copyPixels to copy the pixels from an defined area and finally add thumbs according with number of columns and rows:

[as3]
var thumbBitmap:BitmapData = new BitmapData(bitmapWidth, bitmapHeight);
thumbBitmap.copyPixels(bitmapData, new Rectangle(i * thumbWidth, j * thumbHeight, thumbWidth, thumbHeight), new Point(0, 0));
bitmap = new Bitmap(thumbBitmap);

addChild(bitmap);
bitmap.x = i * (thumbWidth + space);
bitmap.y = j * (thumbHeight + space);
bitmap.smoothing = true;
bitmap.alpha = 0;
[/as3]

Now, let’s say you want to animate each individual thumb. Calling a new function in a random interval, that receive as parameters the Bitmap object and his coordonates, will make the thumb to move to a defined position and after back to his coordonates. This get a random interval, declare a variable c as Number before the for statement. Add a setTimeout method inside of same statement to call the animate function:

[as3]
setTimeout(animate, 1000+ (100*(Math.round(Math.random()*c))), bitmap, bitmap.x, bitmap.y);
[/as3]

and the function that use Caurina to animate the thumbs:

[as3]
private function animate(bitmapSource:Bitmap, bitmapX:Number, bitmapY:Number):void
{
bitmapSource.y = -100;
Tweener.addTween(bitmapSource, { time:0.5, transition:"easeOutSine", x:bitmapX, y:bitmapY, alpha:1} );
}
[/as3]

Now that you know how to manipulate them, you can add multiple effects and play around with them.
Let me know what do you think by sending me emails or comments. Cheers


Twitter Digg Delicious Stumbleupon Technorati Facebook

10 Responses to “Manipulating a loaded image with BitmapData in AS3”

  1. Thanks
    This was on my mind

  2. hi Robert
    about this line
    var thumbBitmap:BitmapData = new BitmapData(bitmapWidth, bitmapHeight);
    I guess you meant
    var thumbBitmap:BitmapData = new BitmapData(thumbWidth,thumbHeight);

  3. No, because later we use:
    thumbBitmap.copyPixels(bitmapData, new Rectangle(i * thumbWidth, j * thumbHeight, thumbWidth, thumbHeight), new Point(0, 0));

    and this line copy the pixels from an area defined as Rectangle with height and width of 100px

  4. very nice fx!!

  5. ezz suggestion solved extra white space issue for me.

  6. Hey, How would you go about reveseing the effect? so full image break apart and bits fly out? also the fix by ezz worked.

  7. Also is there a way to put the actionscript inside the flash project to apply this effect to an image on the stage?

  8. Hmm, why don’t make few movieclips and the play with them, if you are still on timeline?

  9. Hello Robert,

    i tried to use the same code in Flex 4. i can’t understand what is the problem? why it is not working in Flex 4.

    please Help me, nee your urgent help….

    Thanks

  10. Hey..I’m sorry, but I don’t know Flex 🙁