4

私はActionScript3のbitmapDataオブジェクトから特定の色をフィルタリングする効率的な方法を探しています。現在、readByte32()でループを使用しています。これは処理に約1秒かかりますが、これは許容できません。私はpaletMap()を機能させようと試みてきましたが、これまでのところそのAPIを把握できていません(本当に便利なリンクはありますか?Googleは私を失敗させました...)。

これが私の現在のロジックで、改善したいものです。

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()を使用しています。ボイラープレートのものを投稿しませんでした。

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 があります。これは、ピクセル ベンダー フィルタをフラッシュ内の画像に適用する方法に関するアドビのチュートリアルです。

そうしないと、一度に行を処理できます。(コードのわずかなエラーは、幅の反復ごとに高さを再取得することに注意してください):

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 に答える