1

そうですね、2 つの BitmapData を比較したいとしましょう。1 つは背景の画像 (無地ではなく、さまざまなピクセルがあります) で、もう 1 つはまったく同じ背景の上にあるもの (スプライトなど) の画像です。今私がやりたいことは、2 つの画像を比較し、2 番目の画像に存在する背景からすべてのピクセルを削除することによって、2 番目の画像から背景を削除することです。わかりやすくするために、基本的には AS3 でこれを行いたいと考えています。

今、私はこれを行う 2 つの方法を思いつきましたが、どちらも完璧に機能します。1 つはピクセルを直接比較し、もう 1 つはBitmapData.compare()最初にメソッドを使用してから、適切なピクセルを結果にコピーします。私が知りたいのは、どちらの方法がより速いかということです。

これが私の2つの方法です。

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

layer1は背景、layer2は背景が削除されるイメージ、は結果が表示されるresult単なるBitmapDataです。

これらは非常に似ており、個人的には速度の違いに気づいていませんが、どちらが速いか誰かが知っているかどうか疑問に思っていました. 色が同一でない限りピクセルアルファを比較しないため、おそらく方法1を使用しますBitmapData.compare()が、それでも質問しても問題ないと思いました。

4

2 に答える 2

2

これはあなたの状況に100%当てはまるわけではないかもしれませんが、FWIW私はしばらく前にこれについていくつかの調査を行いました。

私はしばらくの間、grant skinners のパフォーマンス テストを試すつもりだったので、これが私の機会でした。

ネイティブ比較、反復比較、逆反復比較 (それらの方が少し速いことがわかっているため)、そして最後にブレンドモード DIFFERENCE を使用した比較をテストしました。

逆反復比較は次のようになります。

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

2 つの画像が一致するかどうかを確認するシェーダーを試し、一致しない場合は、画像のポイントの 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 コードよりも 1 倍高速です。

于 2012-10-08T10:26:52.187 に答える