BitMapDataオブジェクト(またはバイトアレイ)から特定の色をフィルタリングする方法
-
29-09-2019 - |
質問
ActionScript 3のBitMapDataオブジェクトから特定の色をフィルタリングする効率的な方法を探しています。現在、readbyte32()を使用してループを使用しています。これには、受け入れられないプロセスに約1秒かかります。私は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);
これを行うためのより良い方法は、ほんの数00ミリ秒しかかからないと本当に思っています。誰かが私のためにbitmapdataの謎を解き放つことができれば、あなたは私の人々の新しいリーダーになります。
ps私はbitmapdata.lock()を使用しています。ボイラープレートのものを投稿しませんでした。
解決
簡単な方法は、を使用することです しきい値 方法。最初は少し面倒ですが、かなり速いです(あなたが得るのと同じくらい速く)
これにより、すべての赤ピクセル(赤のピクセルのみが正確に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);
他のヒント
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();
}
}
処理にはもう少し時間がかかりますが、少なくともディスプレイはブロックされません。