2009-07-08 3 views
5

Jak zmienić bitmapadę kolorowej mapy bitowej na Czarno-biały w AS3? Pracuję nad prostym narzędziem do edycji grafiki dla CMS w pamięci flash.AS3: Jak zmienić bitmapową bitmapData na czarno-białą?

Ludzie powinni mieć możliwość zmiany koloru przesłanej bitmapy na czarno-białą. Chcę, aby bitmapdata się zmieniła Więc mogę napisać ją do ByteArray z klasą JPGEncoder Adobe później.

Odpowiedz

27

byłoby to najbardziej eleganckie rozwiązanie przypuszczam (z source będąc Ci BitmapData):

const rc:Number = 1/3, gc:Number = 1/3, bc:Number = 1/3; 
source.applyFilter(source.bitmapData, source.bitmapData.rect, new Point(), new ColorMatrixFilter([rc, gc, bc, 0, 0,rc, gc, bc, 0, 0, rc, gc, bc, 0, 0, 0, 0, 0, 1, 0])); 

z flash.geom::Point i flash.filters::ColorMaxtrixFilter ...

ColorMatrixFilter umożliwia wiele rzeczy, takich jak przesunięcia Hue, colorisation, oświetlenie, zaciemnienie i desaturacji i tak dalej ... inaczej BitmapData::paletteMap i BitmapData::colorTransform są dobrym uzupełnieniem ...

prostu chciałem, aby pamiętać, że stosując następujące

const rc:Number = 1/3, gc:Number = 1/2, bc:Number = 1/6; 

wygląda trochę bardziej naturalne, ponieważ subiektywnie, #00FF00 jest jaśniejsza niż #FF0000, który z kolei jest jaśniejsza niż #0000FF

powodzenia wtedy ...;)

greetz

back2dos

+0

To jest właściwe rozwiązanie, +1. – CookieOfFortune

+3

Wydaje mi się pamiętać, że typowa waga kolorów wynosi odpowiednio 30%, 59% i 11% dla R, G i B. Chociaż, jak piszesz, ważenie jest nieco subiektywne, ma korelację z wartościami luminancji kolorów iirc. Twoje ciężary są w tym względzie nieznaczne, ale metoda jest absolutnie poprawna. –

+0

@macke: dzięki, nigdy nie miałem "naukowych" numerów :) – back2dos

2

Cóż, po prostu przy użyciu getPixel i setPixel i uśrednienie kolorów (jestem pewien, że może być w inny sposób to zrobić z filtrem czy coś):

for(int i = 0; i < bitmapData.height; i++) 
{ 
    for(int j = 0; j < bitmapData.width; j++) 
    { 
     var color:uint = bitmapData.getPixel(i, j); 
     var red:uint = color & 0xFF0000 >> 16; 
     var green:uint = color & 0x00FF00 >> 8; 
     var blue:uint = color & 0x0000FF >> 0; 
     var bwColor:uitn = red + green + blue/3; 
     bwColor = bwColor << 16 + bwColor << 8 + bwColor; // puts the average in each channel 

     bitmapData.setPixel(i, j, bwColor); 
    } 
} 
+2

to zadziała, ale jeśli to możliwe, staraj się unikać pętli nad wszystkimi pikselami, dzięki czemu filtr będzie szybszy, ponieważ są natywne. – grapefrukt

0

Próbowałem obu metod. Wygląda na to, że metoda ColorMatrixFilter działa znacznie szybciej podczas pracy z dużymi obrazami.

Czy istnieje sposób na usunięcie filtra? lub czy ja znowu zmieniam wartości ColorMatrixFilter?

+1

Myślę, że po przekonwertowaniu obrazu na czarno-białe nie można wrócić (tracisz informacje podczas konwersji). Zanim zastosujesz filtr, będziesz musiał wykonać kopię. – CookieOfFortune

1

Dzięki Cookie, Kopiowanie oryginalnej bitmapdaty było rzeczywiście najłatwiejszym sposobem na przywrócenie koloru.

function clearColor() { 
     colorbmd = new BitmapData(source.width, source.height); 
     colorbmd = source.clone(); 
     //apply filter here  
    } 
    function restoreColor() { 
     source = colorbmd; 
    } 

myślę kiedy już konwertowane obrazu do czerni i bieli nie można przejść back (Tracisz informacji podczas konwersji ). Zanim zastosujesz filtr, będziesz musiał wykonać kopię . - CookieOfFortune

0

Dziękuję za podejściem, stworzyłem, który pozwala bawić się z wartościami małe narzędzie: http://bjornson.inhb.de/?p=159

Początkowe wartości są te proponowane przez Macke: 30%, 59 % i 11% dla rgb.

Można również załadować obrazy zewnętrzne i wypróbować, aby uzyskać najlepszy efekt dla obrazów.

1

Używam tego snipper:

//Tweens to black and white 
TweenLite.to(DisplayObjectYouWantToTween ,1,{colorMatrixFilter:{matrix:[0.3,0.59,0.11,0, 0,0.3,0.59,0.11,0,0,0.3,0.59,0.11,0,0,0,0,0,1,0]}}); 

//Tween from black and white to Color 
TweenLite.to(DisplayObjectYouWantToTween,1,{colorMatrixFilter:{matrix:[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0]}}); 
2

Faktycznie, można użyć back2dos „s rozwiązanie w znacznie łatwiejszy sposób:

const rc:Number = 1/3, gc:Number = 1/3, bc:Number = 1/3; 
mc.filters = [ new ColorMatrixFilter([rc, gc, bc, 0, 0,rc, gc, bc, 0, 0, rc, gc, bc, 0, 0, 0, 0, 0, 1, 0]) ]; 

gdzie mc jest pojemnik MovieClip lub Sprite którym istnieje BitmapData jako element wizualny. dziękuje back2dos :)