Jun 30

I did a little experimenting with the BitmapData class, and came up with this.
I found this effect from a gallery somewhere, and thought it would be cool to try my hand at it, for learning purposes.

Click on the image below to see the effect.

What’s happening is, I get the size of the image, divide it by the size of the “pixels” I want, then create an array of Rectangles positioned in a grid over the image.
I then fill each Rectangle with the color of the pixel in it’s center by using the getPixel() and fillRect() methods of the BitmapData class.
Here is the central function doing the pixelating.
[sourcecode language='js']
private function pixelate(bitmap:Bitmap, strength:Number):void {
var _x:int = 0; // position of the rectangle
var _y:int = 0;
if (strength > 1){
_strength = 1;
}
var _strength:Number = strength; // multiplier for size of “pixels”

var _w:Number = bitmap.bitmapData.width * _strength; //size of “pixels”
var _h:Number = bitmap.bitmapData.height * _strength;

var nH:int = Math.ceil(bitmap.bitmapData.width / _w); // number of rectangles needed horizontally
var nV:int = Math.ceil(bitmap.bitmapData.height / _h);// number of rectangles needed vertically

var rectangles:Array = []; // Rectangles array

//create rectangles
for (var i:int = 0; i < nV; i ++){
var targH:Number = _h;
if (i >= nV - 1){
targH = bitmap.bitmapData.height - _y;
}
for (var j:int = 0; j < nH; j ++){
var targW:Number = _w;
if (j >= nH - 1){
targW = bitmap.bitmapData.width - _x;
}
rectangles.push(new Rectangle(_x, _y, targW, targH));
_x += _w;
}
_x = 0;
_y += _h;

}
//fill in rectangles
for (i = 0; i < rectangles.length; i++){

var rect:Rectangle = rectangles[i];
var pix:uint = _states[0].getPixel((rect.x + rect.width / 2), (rect.y + rect.height / 2));
bitmap.bitmapData.fillRect(rect, pix);
}

saveCurrentState(bitmap.bitmapData);

}
[/sourcecode]

Now for the reverting to the original image part, I had to improvise. Since I overwrote the BitmapData with a bunch of filled rectangles, I couldn’t do much with it.
So I used an array which stores each “state” the BitmapData is in. And I could just retrieve the BitmapData in the array and copy it into the original BitmapData.
[sourcecode language='js']
private function saveCurrentState(bitmapData:BitmapData):void {
_states.push(bitmapData.clone());
}
private function revertToState(stage:int):void {
try{
bmData.copyPixels(_states[stage], bmData.rect, new Point(bmData.rect.x, bmData.rect.y));
}catch (e:Error){
throw new Error(”Invalid state. “);
}
}
[/sourcecode]
To create the animation, I just called the pixelate() function through a Timer at 300 milliseconds.


one comment so far...

leave a reply