2009-07-08 5 views
5

Wie kann ich die Bitmapdaten einer farbigen Bitmap zu Schwarz und Weiß in AS3 ändern? Ich entwickle ein einfaches Bildbearbeitungsprogramm für ein CMS in Flash.AS3: Wie man BitmapData eines farbigen Bitmap zu Schwarzweiss ändert?

Benutzer sollten in der Lage sein, die Farbe der hochgeladenen Bitmap in Schwarzweiß zu ändern. Ich möchte die Bitmapdaten selbst ändern Also kann ich es später in einem ByteArray mit Adobe JPGEncoder Klasse schreiben.

Antwort

27

dies wäre die eleganteste Lösung ich nehme an (mit source Sie BitmapData zu sein):

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

mit flash.geom::Point und flash.filters::ColorMaxtrixFilter ...

ermöglicht viele Dinge, wie Farbtonverschiebungen, colorisation, aufhellen, abdunkeln und Desaturierung und so weiter ... sonst BitmapData::paletteMap und BitmapData::colorTransform sind gute Ergänzungen ...

nur beachten, wollte, dass die Verwendung folgender

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

sieht ein wenig natürlicher, subjektiv, da #00FF00 heller als #FF0000, was wiederum heller als #0000FF

viel Glück dann ...;)

greetz

back2dos

+0

Dies ist die richtige Lösung, +1. – CookieOfFortune

+3

Ich erinnere mich, dass eine typische Gewichtung der Farben 30%, 59% und 11% für R, G und B ist. Obwohl die Gewichtung etwas subjektiv ist, korreliert sie mit den Luminanzwerten der Farben. Ihre Gewichte sind in dieser Hinsicht ein wenig aus, aber die Methode ist absolut richtig. –

+0

@Macke: Danke, hatte nie die "wissenschaftlichen" Zahlen :) – back2dos

2

Nun, nur getPixel und setPixel verwenden, und Mittel die Farben (ich bin sicher, es kann eine andere Möglichkeit, dies mit einem Filter oder etwas zu tun):

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

das wird funktionieren, aber wenn möglich, versuchen zu vermeiden, über alle Pixel einen Filter zu durchlaufen wird viel schneller sein, da sie nativ sind. – grapefrukt

0

habe ich versucht, beide Methoden. Scheint so, als ob die ColorMatrixFilter-Methode beim Arbeiten mit großen Bildern viel schneller arbeitet.

Gibt es eine Methode, um den Filter zu entfernen? oder sollte ich die ColorMatrixFilter-Werte erneut ändern?

+1

Ich denke, sobald Sie das Bild in Schwarz und Weiß umgewandelt haben, können Sie nicht zurück gehen (Sie verlieren Informationen während der Konvertierung). Sie müssen eine Kopie erstellen, bevor Sie den Filter anwenden. – CookieOfFortune

1

Dank Cookie, Kopieren der ursprünglichen Bitmapdaten war in der Tat die einfachste Lösung, um Farbe wiederherzustellen.

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

Ich denke, sobald Sie das Bild in Schwarzweiß umgewandelt haben Sie nicht zurück gehen können (Sie verlieren Informationen während der Umwandlung). Bevor Sie den Filter anwenden, müssen Sie eine Kopie erstellen. - CookieOfFortune

0

Danke für den Ansatz, habe ich ein kleines Tool, das Sie mit den Werten rumspielen können: http://bjornson.inhb.de/?p=159

Die Anfangswerte sind die von macke vorgeschlagen diejenigen: 30%, 59 % und 11% für rgb.

Sie können auch externe Bilder laden und das beste Ergebnis für Ihre Bilder ausprobieren.

1

Ich benutze diese 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

tatsächlich, Sie back2dos ‚s-Lösung in einem viel einfacheren Weg nutzen können:

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

wo mc der MovieClip- oder Sprite Container ist, wo die BitmapData- existiert als visuelles Element. danke back2dos :)