1

对,假设我想比较两个 BitmapData。一个是背景图像(不是实心的,它有不同的像素),另一个是完全相同的背景之上的某物(如精灵)。现在我想要做的是从第二个图像中删除背景,通过比较两个图像,并从背景中删除第二个图像中存在的所有像素。为了清楚起见,基本上我想在 AS3中执行此操作。

现在我想出了两种方法来做到这一点,它们都可以完美地工作。一个直接比较像素,而另一个BitmapData.compare()先使用该方法,然后将适当的像素复制到结果中。我想知道哪种方式更快。

这是我的两种方法:

方法一

for (var j:int = 0; j < layer1.height; j++)
{
    for (var i:int = 0; i < layer1.width; i++)
    {
        if (layer1.getPixel32(i, j) != layer2.getPixel32(i, j))
        {
            result.setPixel32(i, j, layer2.getPixel32(i, j));
        }
    }
}

方法二

result = layer1.compare(layer2) as BitmapData;

for (var j:int = 0; j < layer1.height; j++)
{
    for (var i:int = 0; i < layer1.width; i++)
    {
        if (result.getPixel32(i, j) != 0x00000000)
        {
            result.setPixel32(i, j, layer2.getPixel32(i, j));
        }
    }
}

layer1是背景,layer2是背景将被删除的图像,并且result只是BitmapData结果将出现的图像。

这些非常相似,我个人没有注意到速度上有任何差异,但我只是想知道是否有人知道哪个会更快。无论哪种方式,我都可能会使用方法 1,因为BitmapData.compare()除非颜色相同,否则不会比较像素 alpha,但我仍然认为问它不会有坏处。

4

2 回答 2

2

这可能不是 100% 适用于您的情况,但是 FWIW 我不久前对此进行了一些研究,这是我当时写的:

一段时间以来,我一直想尝试 grant skinners 性能测试,所以这是我的机会。

我测试了本机比较、迭代比较、反向迭代比较(因为我知道它们要快一点),最后使用混合模式差异进行比较。

反向迭代比较如下所示:

for (var bx:int = _base.width - 1; bx >= 0; --bx) {
 for (var by:int = _base.height - 1; by >= 0; --by) {
  if (_base.getPixel32(bx, by) != compareTo.getPixel32(bx, by)) {
   return false;
  }
 }
}
return true;

混合模式比较如下所示:

var test:BitmapData = _base.clone();
test.draw(compareTo, null, null, BlendMode.DIFFERENCE);
var rect:Rectangle = test.getColorBoundsRect(0xffffff, 0x000000, false);
return (rect.toString() != _base.rect.toString());

我不是 100% 确定这是完全可靠的,但它似乎工作。

我在 500x500 图像上运行了每个测试 50 次迭代。

不幸的是,我的像素弯曲工具包很糟糕,所以我无法尝试这种方法。

每个测试都在调试和发布播放器中运行以进行比较,请注意巨大的差异!

完整代码在这里:http ://webbfarbror.se/dump/bitmapdata-compare.zip

图形

于 2012-10-08T09:51:53.930 回答
1

您可以尝试使用着色器来检查两个图像是否匹配,如果不匹配,则将其中一个图像的点保存为输出。像这样:

kernel NewFilter
<    namespace : "Your Namespace";
     vendor : "Your Vendor";
     version : 1;
     description : "your description";
>
{
    input image4 srcOne;
    input image4 srcTwo;
    output pixel4 dst;

    void evaluatePixel()
    {
        float2 positionHere = outCoord();
        pixel4 fromOne = sampleNearest(srcOne, positionHere);
        pixel4 fromTwo = sampleNearest(srcTwo, positionHere);
        float4 difference=fromOne-fromTwo;
        if (abs(difference.r)<0.01&&abs(difference.g)<0.01&&abs(difference.b)<0.01) dst=pixel4(0,0,0,1); 
        else dst = fromOne;
    }
}

如果匹配,这将返回黑色像素,如果不匹配,则返回第一个图像的像素。使用 Pixel Bender 使其在 Flash 中运行。一些教程在这里。着色器通常比普通的 AS3 代码更快。

于 2012-10-08T10:26:52.187 回答