我正在尝试用ActionScript3编写自己的floodfill函数,因为Adobe提供的函数不够灵活(您只能给出一种目标颜色,我想给出一系列目标颜色)。
所以,到目前为止,我想出的可怕的代码是:
private function beginAlgortime(xx:int,yy:int):void
{
if (bmp.bitmapData.getPixel(xx, yy) != 0x333333) {
bmp.bitmapData.setPixel(xx, yy, 0x333333);
beginAlgortime(xx + 1, yy);
beginAlgortime(xx + 1, yy+1);
beginAlgortime(xx + 1, yy - 1);
beginAlgortime(xx , yy+1);
beginAlgortime(xx , yy - 1);
beginAlgortime(xx - 1, yy);
beginAlgortime(xx - 1, yy+1);
beginAlgortime(xx - 1, yy-1);
}
}
一个非常基本的递归函数..但很明显,使用这种方法,flash播放器对我来说很糟糕:)有人有解决这个问题的办法吗?干杯!
发布于 2010-02-23 18:51:48
没有必要直接递归到对角线,因为垂直和水平递归无论如何都会击中这些像素。
你说的floodfill到底是什么意思?你说的“颜色范围”是什么意思?
您提供的例程将用0x333333填充整个位图。并且它不会终止,因为您从不检查是否离开位图边界。
发布于 2010-02-25 05:36:30
您可以尝试将其从递归函数转换为使用数组而不是程序堆栈的迭代函数。
下面是the article Allan mentioned中描述的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);
}
编辑:在尝试了几种方法来跟踪已经搜索到的像素之后,我意识到使用第二个BitmapData实例效果非常好。我已经相应地更新了代码。
这段代码在我的计算机上填充2000x1400位图只需大约14秒。为了获得更好的用户体验,您应该将填充过程分解为多个帧,这样用户就不必盯着等待的图标。
哦,这仍然只影响一种颜色,但它应该很容易修改为采用多种颜色,或颜色阈值,或类似。
添加编辑:维基百科上的Flood fill文章有几个算法建议。
https://stackoverflow.com/questions/2317018
复制相似问题