Here’s a Class the returns an array of points from all positions in a BitmapData object with transparency (either display objects like shapes or textfields, or loaded PNGs with transparency). Each point is one that has a neighboring pixel that is transparent. It’s pretty fast – much faster than what’s out there – but not quite as flexible. It could easily be modified to check for pixels of a certain color, or threshold of colors, rather than transparency (if you wanted to get the outline of the foreground of a jpeg with a white background, for example).

I originally extended Array (which meant it needed to be dynamic), but performance suffered – the returns are now in a public property called points.

[as3]
package {

import flash.display.BitmapData;
import flash.geom.Point;

public class Outline {

private static const SPOTS:Array = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];

private var bitmapData:BitmapData;

private var pixelTable:Array;

private var rows:uint;
private var cols:uint;

public var points:Array;

public function Outline(bmd:BitmapData):void {

points = [];

bitmapData = bmd;

initialize();
}

private function hasTransparentNeighbor(rowIndex:uint,cellIndex:uint):Boolean {

var spot:Array;
var rowNum:int;
var cellNum:int;
var row:Array;

for (var i:int = 0; i < 8; i++) {
spot = SPOTS[i];
rowNum = rowIndex + spot[0];
if (rowNum > -1) {
if (rowNum < rows) {
cellNum = cellIndex + spot[1];
if (cellNum > -1) {
row = pixelTable[rowNum];
if (cellNum < cols) {
if (!row[cellNum]) {
return true;
}
}
}
}
}
}
return false;
}

private function populate():void {
for (var i:int=0; i < rows; i++) {
for (var j:int=0; j < cols; j++) {
if (pixelTable[i][j]) {
if (hasTransparentNeighbor(i,j)) {
points.push(new Point(j, i));
}
}
}
}
}

private function initialize():void {

rows = bitmapData.height;
cols = bitmapData.width;

pixelTable = new Array(rows);

var row:Array;

for (var i:int=0; i < rows; i++) {
row = [];
for (var j:int=0; j < cols; j++) {
row[j] = bitmapData.getPixel32(j, i) >> 24 & 0xFF;
}
pixelTable[i] = row;
}

populate();
}

}

}
var outline:Outline = new Outline(_some_bitmap_data_object);
trace(outline.points);
[/as3]