2012-10-08 59 views
1

对,我们假设我想比较两个BitmapDatas。一个是背景图像(不是固体,它具有不同的像素),另一个是背景完全相同的东西(如精灵)。现在我想要做的是从第二张图片中删除背景,比较两张图片,并从背景中删除第二张图片中的所有像素。 为了清楚起见,我基本上想在AS3中做thisAS3 - 比较BitmapDatas,最快的方法?

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

这里是我做这件事的方法有两种:

方法1

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

方法2

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

​​为背景,layer2是图片的背景将从中删除,并result只是一个BitmapData,结果会出来。

这些非常相似,我个人并没有注意到速度上的差异,但我只是想知道是否有人知道哪个更快。我可能会使用方法1,因为BitmapData.compare()不会比较像素阿尔法,除非颜色相同,但我仍然认为它不会受到伤害。

回答

2

这可能并不适用于您的情况为100%,但FWIW我做了一些研究,这一段时间回来,这是我回了信,然后:

我一直尝试授予斯金纳性能测试有一段时间了,所以这是我的机会。

我测试了原生比较,迭代比较,反向迭代比较(因为我知道它们有点快),最后使用blendmode差分进行比较。

反向反复比较,如下所示:

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; 

应用blendMode比较喜欢这个样子:

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次迭代的每次测试。

不幸的是我的像素弯曲工具包是borked,所以我不能尝试这种方法。

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

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

graph

+0

嗯,有趣。看起来像blendmode是最好的选择,本地比较是相当不错的,但对于非常不同,这是一个很大的变化。速度对我来说不是最大的问题,但我会研究BlendModes是如何工作的。我不会将此标记为答案,以防其他人不得不说,但谢谢! – puggsoy

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中运行。一些教程是here。着色器通常比普通的AS3代码更快。