如何从 bitmapData 对象(或字节数组)中过滤特定颜色

发布于 2024-09-07 01:03:45 字数 962 浏览 17 评论 0原文

我正在寻找一种有效的方法来从 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);
  }
 }
}

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

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();我只是没有发布样板内容。

I'm looking for an efficient way to filter a specific color from a bitmapData object in ActionScript 3. Currently I use a loop with readByte32(). This takes about a second to process which is unacceptable. I have been trying to get paletteMap() to work but so far haven't been able to grasp its API (any truly useful links? Google has failed me...).

Here's my current logic, which I want to improve:

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);
  }
 }
}

I can get slightly better performance from using Vectors but it's only marginally better...

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);

I really think there must be a better way to do this that only takes a few 100 milliseconds. If anyone can unlock the mysteries of bitmapData for me, you will be the new leader of my people.

PS I am using bitmapData.lock() and unlock(); I just didn't post the boilerplate stuff.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

写给空气的情书 2024-09-14 01:03:45

一种简单的方法是使用阈值< /a> 方法。一开始有点麻烦,但速度相当快(我认为尽可能快)

这会将每个红色像素(仅考虑红色像素,其值恰好为 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);

An easy way is using the threshold method. It's a bit cumbersome at first, but it's pretty fast (as fast as you'll get, I think)

This will change every red pixel (considering red only a pixel whose value is exactly 0xffff0000) to blue (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);
一个人的夜不怕黑 2024-09-14 01:03:45

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

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

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();
    }
}

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

Flash has an API to a shader like language called pixel bender that may be of use to you in this case. Here is a tutorial from adobe on how to apply a pixel bender filter to an image in flash.

Otherwise you could processes rows at a time. (Note a slight error in your code was to re-get the height on each iteration of width):

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();
    }
}

The processing will take a bit longer but at least your display won't be blocked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文