再帰関数から、プログラム スタックの代わりに配列を使用する反復関数に変換してみてください。
Allan が言及した記事で説明されているように、FloodFill の反復実装を次に示します。
function floodFill(bmpData:BitmapData, startX:int, startY:int, fill:uint, old:uint):void
{
var queue:Array = new Array();
queue.push(new Point(startX, startY));
var iterations:uint = 0;
var bmpWidth:int = bmpData.width;
var bmpHeight:int = bmpData.height;
var searchBmp:BitmapData = new BitmapData(bmpData.width, bmpData.height);
var currPoint:Point, newPoint:Point;
while (queue.length > 0)
{
currPoint = queue.shift();
++iterations;
if (currPoint.x < 0 || currPoint.x >= bmpWidth) continue;
if (currPoint.y < 0 || currPoint.y >= bmpHeight) continue;
searchBmp.setPixel(currPoint.x, currPoint.y, 0x00);
if (bmpData.getPixel(currPoint.x, currPoint.y) == old)
{
bmpData.setPixel(currPoint.x, currPoint.y, fill);
if (searchBmp.getPixel(currPoint.x + 1, currPoint.y) == 0xFFFFFF)
{
queue.push(new Point(currPoint.x + 1, currPoint.y));
}
if (searchBmp.getPixel(currPoint.x, currPoint.y + 1) == 0xFFFFFF)
{
queue.push(new Point(currPoint.x, currPoint.y + 1));
}
if (searchBmp.getPixel(currPoint.x - 1, currPoint.y) == 0xFFFFFF)
{
queue.push(new Point(currPoint.x - 1, currPoint.y));
}
if (searchBmp.getPixel(currPoint.x, currPoint.y - 1) == 0xFFFFFF)
{
queue.push(new Point(currPoint.x, currPoint.y - 1));
}
}
}
trace("iterations: " + iterations);
}
編集:既に検索されたピクセルを追跡する方法をいくつか試した後、2 つ目の BitmapData インスタンスを使用すると非常にうまく機能することがわかりました。それに応じてコードを更新しました。
このコードは、私のコンピューターで 14 秒以内に 2000x1400 のビットマップを塗りつぶします。ユーザー エクスペリエンスを向上させるには、塗りつぶし処理を複数のフレームに分割して、ユーザーが待機中のアイコンを凝視する必要がないようにする必要があります。
ああ、これはまだ 1 つの色にしか影響しませんが、複数の色や色のしきい値などを使用するように簡単に変更できるはずです。
編集して追加:ウィキペディアのフラッド フィルの記事には、いくつかのアルゴリズムの提案があります。