2010-06-22 3 views
4

ActionScript 3에서 bitmapData 객체의 특정 색상을 필터링하는 효율적인 방법을 찾고 있습니다. 현재는 readByte32() 루프를 사용하고 있습니다. 이것은 받아 들일 수없는 과정에 약 1 초가 걸립니다. paletteMap()을 사용하려고 노력했지만 지금까지 API (모든 유용한 링크? Google은 나를 실패했습니다 ...)를 파악할 수 없었습니다. 난 정말이 생각bitmapData 객체 (또는 바이트 배열)에서 특정 색상을 필터링하는 방법

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

...

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

내가 벡터를 사용하여 약간 더 나은 성능을 얻을 수 있지만 그것은 단지 변두리에 더 나은 :

는 여기에 내가 향상시키고 자하는 나의 현재의 논리입니다 이 작업을 수행하는 더 좋은 방법은 100 밀리 초 밖에 걸리지 않습니다. 누구든지 나를 위해 bitmapData의 신비를 풀 수 있다면 내 사람의 새로운 리더가 될 것입니다.

PS bitmapData.lock() 및 unlock();을 사용하고 있습니다. 나는 그 보일러 판 물건을 게시하지 않았다.

답변

4

쉬운 방법은 threshold 방법을 사용하는 것입니다.

이렇게하면 모든 빨간색 픽셀 (빨강 값이 ​​정확히 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); 
+0

고마워, 내가 이것을 시도하고 성능을 비교하자. 너에게 다시 돌아갈 게. – user372950

+0

그냥 놀랍습니다. threshold() 사용은 위의 시도보다 100 배 이상 빠릅니다. 나는 그런 복잡한 방법이 그렇게 빨리 작동한다고 믿을 수 없다. 정말 고맙습니다! – user372950

+1

@jpwrunyan. 문제 없어. 'threshold'는 여러분의 코드가하는 것과 거의 동일하게 여기에 있습니다. 하지만 큰 차이점은 기본적으로 실행된다는 것입니다. 이것은 항상 모든 액션 스크립트를 이길 것입니다. 엄지 손가락의 규칙에 따라 setPixel/getPixel 호출을 볼 때마다, 특히 빡빡한 루프에서 호출 할 때마다 네이티브 함수로 바꾸는 방법을 찾으십시오. 그렇게 할 수 없다면 픽셀 벤더가 도움이 될 수 있지만 원시 코드만큼 빠르지는 않습니다. –

1

플래시에는이 경우에 유용 할 수있는 pixel bender이라는 언어와 같은 셰이더 API가 있습니다. 여기 어도비의 튜토리얼은 apply a pixel bender filter to an image in flash입니다.

그렇지 않으면 한 번에 한 행을 처리 할 수 ​​있습니다. (코드에서 약간의 오차 폭의 각 반복에 다시 얻을 높이에 있었다 주) :

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

처리는 길어질 것이다 그러나 적어도 디스플레이는 차단되지 않습니다.

+0

첫 번째 이중 루프 버전에서 오류를 지적 해 주셔서 감사합니다! 그러나 왜 위의 타이머를 사용하는지 잘 모르겠습니다. 나는 효과를 애니메이션화하지 않을 것이다. 난 그냥 이미지를 처리하고 이미지에서 (0x00000000로 대체) 매우 구체적인 색상을 제거해야합니다. – user372950

관련 문제