Working with pixels

The release of Flash 8 gave us a powerful object, the BitmapData object. This object gives us a lot of control over bitmap images, and the opportunity to create some really amazing effects. In this tutorial I am going to go over the basics of manipulating a bitmapData object, and controlling the movement of each individual pixel within it.

The pixel object

A 200x200 pixel image has 40 000 pixels in it, that’s a lot of data to manage, so a simple data object comes in really handy. Here is a simple object that just contains a few values. This object will represent one pixel in our final application. In my demo, and the attached source code, this is this is the Pixel.as file.

var px:Number; //the pixel's x position
var py:Number; //the pixel's y position
var ox:Number; //the pixel's original x position
var oy:Number; //the pixel's original y position
var c:uint; //the pixels colour

Animating it

The next step is to actually take a bitmap image and create one of these objects for each of its pixels. We do this by looping over each pixel individually, and using its data to construct our object. As we create these pixels we also save them to an array so that we can access them at a later time.

In this sample code, I use a nested for loop to accomplish this task. It goes through the pixels row by row using the getPixel method of a bitmap data object to return that pixels colour value. The two loop’s values, i and j, tell me the pixels position, and with those I create the pixel object.

for(var i:int = 0; i < myBitmapData.height; i++) {
    for(var j:int = 0; j < myBitmapData.width; j++) {
        var colour:uint = myBitmapData.getPixel(j, i);
        var p:Pixel = new Pixel(j, i, colour);
        _pixels.push(p);
    }
}

At this point we have the information we need to perform a pixel based animation. Using an EnterFrame loop, we can cycle over our pixel objects and update their positions every time the frame refreshes. Lets take a look at an example where the pixels follow the mouse around.

private function render(e:Event):void {
    //lock the bitmapData object so it doesn't update until I'm done
    _myBitmapData.lock();
    //clear the object of old pixels
    _myBitmapData.fillRect(new Rectangle(0,0,stageWidth,stageHeight),0x00000000);

    var l:int = _pixels.length;
    for(var i:int = 0; i < l; i++) {
        var p:Pixel = _pixels[i] as Pixel;
        //a simple chase formula determines the mouse's new position
        p.px -= (p.px - (p.ox+mouseX))*p.speed;
        p.py -= (p.py - (p.oy+mouseY))*p.speed;
        //apply the information as a new pixel on the object
        _myBitmapData.setPixel(p.px,p.py,p.c);
    }

    //unlock it so the update takes place
    _myBitmapData.unlock();
}

In this example you will notice that a new value has been added to the pixel object called speed. Speed is a random number between 0-1, that I am creating on every new pixel object. This example works fine without this extra value, however, when all the pixels move at the same speed they don’t look like pixels, but rather an image. The random speed value allows them to move separately so that we can actually see the effect taking place.

Below is an example of what it looks like.

The example files are here.

Comments

Comment functionality has been disabled. Contact me on Twitter.

Pablo said:

I was thinking bout how you did this the other day and you did it the way I thought. I thought it would be slow to update each pixel in a for loop & enter frame however it does look good. Cheers Tyler.

Brett said:

I guess I have to post something today. How does some popforge setup action sound?

unklewood said:

woah, that is SWEET! nice work, t-skillet.

Recent & Popular Articles

Browse All >