Pixelated video effect [Part II]

space

I few weeks ago I posted a pixelation effect. I have since optimised the code and also added in support for webcam input.

Checkout the demo and source code below.

This movie requires Flash Player 10

Here is an explanation of the technique.

First get the bitmapData source from the video input. Then divide the data into a grid of new bitmaps using a double for-loop. Store each one these in a two dimensional array.

private function createBitmapGrid():void {

			var source:BitmapData = getVideoSource();

			var _w:Number=source.width;
			var _h:Number=source.height;
			var rows:Number=source.height/_divideGridBy; // cols
			var cols:Number=source.width/_divideGridBy; // rows
			var cellWidth:Number = _w/cols-_cellpadding;
			var cellHeight:Number = _h/rows-_cellpadding

			for (var i:uint=0; i<cols; i++) {
				for (var j:uint=0; j<rows; j++) {
					var tempBitmapData:BitmapData=new BitmapData(cellWidth,cellHeight, true, 0x000000);
					var tempBitmap:Bitmap =new Bitmap(tempBitmapData);
					tempBitmap.x=i*_w/cols;
					tempBitmap.y=j*_h/rows;
					if(! _particleArray[i])
					_particleArray[i] = {};
					_particleArray[i][j] = tempBitmap;
					_holder.addChild(tempBitmap);
				}
			} 			

		}

Then add an enterframe listener to update the all the bitmap cells in the grid. Add a double for-loop to go through each cell. Use the copyPixel function to copy a rectangular portion of the source image to each cell. After you copy the source data, find the average brightness of the cell and use it as a variable to adjust the z value of the bitmap cell.

this.addEventListener(Event.ENTER_FRAME, updateBitmapGrid);
private function updateBitmapGrid(e:Event):void {

			var source:BitmapData = getVideoSource();

			var _w:Number=source.width;
			var _h:Number=source.height;
			var rows:Number=source.height/_divideGridBy; // cols
			var cols:Number=source.width/_divideGridBy; // rows
			var cellWidth:Number = _w/cols-_cellpadding;
			var cellHeight:Number = _h/rows-_cellpadding

			for (var i:uint=0; i<cols; i++) {
				for (var j:uint=0; j<rows; j++) {
					var tempBitmap:Bitmap = null;
					if (_particleArray[i]) {
						if(_particleArray[i][j]){
							tempBitmap=_particleArray[i][j];
						}
					}
					if(tempBitmap != null){
						var p:Point = new Point(0, 0);
						var rect:Rectangle = new Rectangle(tempBitmap.x+_cellpadding, tempBitmap.y+_cellpadding, cellWidth, cellHeight);
						tempBitmap.bitmapData.copyPixels(source, rect, p);
						var color:Number=getAverageColour(tempBitmap.bitmapData);
						var brightness:Number=getBrightness(getAverageColour(tempBitmap.bitmapData));
						if(_moveZ)
						tempBitmap.z = 255 - (brightness * 1);

					}
				}
			}
		}
private function getAverageColour( source:BitmapData ):Number {
			var red:Number=0;
			var green:Number=0;
			var blue:Number=0;

			var count:Number=0;
			var pixel:Number;

			for (var x:Number = 0; x < source.width; x++) {
				for (var y:Number = 0; y < source.height; y++) {
					pixel=source.getPixel(x,y);

					red+=pixel>>16&0xFF;
					green+=pixel>>8&0xFF;
					blue+=pixel&0xFF;

					count++;
				}
			}

			red/=count;
			green/=count;
			blue/=count;

			return red << 16 | green << 8 | blue;
		}

		private function getBrightness(colour:Number):Number {
			var R:Number=0;
			var G:Number=0;
			var B:Number=0;

			R+=colour>>16&0xFF;
			G+=colour>>8&0xFF;
			B+=colour&0xFF;

			var br:Number=Math.sqrt(R*R*.241+G*G*.691+B*B*.068);
			return br;
		}

Download package