4

我正在寻找一种从 ActionScript 3 中的 bitmapData 对象中过滤特定颜色的有效方法。目前我使用带有 readByte32() 的循环。这需要大约一秒钟的时间来处理,这是不可接受的。我一直在尝试让 paletteMap() 工作,但到目前为止还无法掌握它的 API(任何真正有用的链接?谷歌让我失望了......)。

这是我目前的逻辑,我想改进:

var n:int = bitmapData.width;
for (var i:int = 0; i < n; i++) {
 var m:int = bitmapData.height;
 for (var j:int = 0; j < m; j++) {
  var color:int = bitmapData.getPixel(i, j);
  if (color == 0xCACACA) {
   bitmapData.setPixel32(i, j, 0x00000000);
  }
 }
}

我可以通过使用 Vectors 获得更好的性能,但它只是稍微好一点......

var v:Vector.<uint> = bitmapData.getVector(bitmapData.rect);
var n:int = bitmapData.width * bitmapData.height;
for (var i:int = 0; i < n; i++) {
 var color:uint = v[i];
 v[i] = color == 0xFFCACACA ? 0x00000000 : color;
}
bitmapData.setVector(bitmapData.rect, v);

我真的认为必须有更好的方法来做到这一点,只需要几百毫秒。如果有人能为我解开bitmapData的奥秘,你就是我族人的新领袖。

PS 我正在使用 bitmapData.lock() 和 unlock(); 我只是没有发布样板文件。

4

2 回答 2

4

一种简单的方法是使用阈值方法。一开始有点麻烦,但它很快(我想你会很快)

这会将每个红色像素(仅考虑红色像素,其值恰好为 0xffff0000)更改为蓝色 (0xff0000ff)。

var colorToReplace:uint = 0xffff0000;
var newColor:uint = 0xff0000ff;
var maskToUse:uint = 0xffffffff;

var rect:Rectangle = new Rectangle(0,0,bitmapData.width,bitmapData.height);
var p:Point = new Point(0,0);
bitmapData.threshold(bitmapData, rect, p, "==", colorToReplace, 
        newColor, maskToUse, true);
于 2010-06-22T13:40:47.263 回答
1

Flash 有一个类似于着色器的 API,称为像素弯曲器,在这种情况下可能对您有用。这是 adobe 关于如何将像素弯曲滤镜应用于 flash 中的图像的教程。

否则,您可以一次处理行。(请注意,您的代码中的一个小错误是在每次宽度迭代时重新获取高度):

private var currentRow:Number = 0;
private var timer:Timer;
public function processImage(event:Event=null):void
{
    var m:int = bitmapData.height;
    for (var j:int = 0; j < m; j++)
    {
        if (bitmapData.getPixel(currentRow, j) == 0xCACACA)
        {
            bitmapData.setPixel32(currentRow, j, 0x00000000);
        }
    }

    currentRow++;
    if(currentRow < bitmapData.width)
    {
        timer = new Timer(1, 500);
        timer.addEventListener(TimerEvent.COMPLETE, processImage);
        timer.start();
    }
}

处理将花费更长的时间,但至少您的显示不会被阻止。

于 2010-06-22T09:45:06.410 回答