2010-11-22 5 views
1

Ich habe einige PNG-Dateien, denen ich eine Farbe anwende. Die Farbe ändert sich abhängig von einer Benutzerauswahl. Ich ändere die Farbe über 3 RGB-Werte von einer anderen Methode. Die PNG-Dateien sind eine zufällige Form mit voller Transparenz außerhalb der Form. Ich möchte die Transparenz nicht ändern, nur den RGB-Wert. Momentan setze ich die RGB-Werte Pixel für Pixel (siehe Code unten).Schnellere Methode zum Festlegen einer (PNG) Bitmapfarbe anstelle von Pixel für Pixel

Ich bin zu der Erkenntnis gekommen, dass dies unglaublich langsam und möglicherweise nicht effizient genug ist, in einer Anwendung zu tun. Gibt es einen besseren Weg, dies zu tun?

Hier ist, was ich gerade mache. Sie können sehen, dass die Pixelanordnung für ein Bild ist enorm, die einen anständigen Teil des Bildschirms einnimmt:

public void foo(Component component, ComponentColor compColor, int userColor) { 
    int h = component.getImages().getHeight(); 
    int w = component.getImages().getWidth(); 
    mBitmap = component.getImages().createScaledBitmap(component.getImages(), w, h, true); 

    int[] pixels = new int[h * w]; 

    //Get all the pixels from the image 
    mBitmap[index].getPixels(pixels, 0, w, 0, 0, w, h); 

    //Modify the pixel array to the color the user selected 
    pixels = changeColor(compColor, pixels); 

    //Set the image to use the new pixel array 
    mBitmap[index].setPixels(pixels, 0, w, 0, 0, w, h); 
} 

public int[] changeColor(ComponentColor compColor, int[] pixels) { 
    int red = compColor.getRed(); 
    int green = compColor.getGreen(); 
    int blue = compColor.getBlue(); 
    int alpha; 

    for (int i=0; i < pixels.length; i++) { 
     alpha = Color.alpha(pixels[i]); 
     if (alpha != 0) { 
      pixels[i] = Color.argb(alpha, red, green, blue); 
     } 
    } 
    return pixels; 
} 
+1

Vielleicht könnten Sie ein Bild mit einer Palette verwenden? Da Sie eine Farbe für alles verwenden, bedeutet das, dass Sie sowieso nur 256 mögliche Pixelfarben von einem Eingang bekommen können (da die RGB-Teile gleich sind und nur der A-Teil variiert). Wenn Ihr Bild eine Palette mit 256 verschiedenen Farben hat, die sich nur im Wert des Alphakanals unterscheiden, müssten Sie nur die Palette und nicht die Bilddaten selbst ändern. –

+0

Ich verstehe Sie entweder nicht oder Sie verstehen meine Frage nicht wirklich. Jedes Bild, das ich modifizieren möchte, hat 2 Alpha-Werte, vollständig transparent und durchscheinend/opak. Ich möchte die RGB-Werte ändern und die Alpha-Werte beibehalten. Das heißt, während ich das Konzept einer Palette, gibt es keine Palette-Klasse in Android. Was schlägst du vor, von dem ich gelesen habe? – user432209

+0

@user: Ja, die Idee ist, dass, wenn Ihre PNG-Datei eine Palette verwendet, Sie die Pixel nicht ändern müssen, nur die Palette. Selbst ohne SDK-Unterstützung könnten Sie möglicherweise die PNG-Datei selbst als Rohdaten lesen und die Palette im Speicher ändern, bevor Sie sie über einen Speicherstream laden. Es ist keine sehr schöne Lösung, aber es kann immer noch zu einer Leistungsverbesserung führen, wenn Sie es brauchen und niemand bessere Ideen hat. Es sollte jedoch relativ einfach sein, da Sie sich nicht mit komprimierten Daten beschäftigen müssen. Einzelheiten finden Sie in [PNG-Spezifikationen] (http://www.w3.org/TR/2003/REC-PNG-20031110/). –

Antwort

2

Haben Sie bei den Funktionen sah in Bitmap zur Verfügung? Etwas wie extractAlpha klingt, als könnte es nützlich sein. Sie sehen auch, wie solche Funktionen in Android implementiert werden, um zu sehen, wie Sie es an Ihren speziellen Fall anpassen können, wenn es nicht genau Ihren Bedürfnissen entspricht.

+0

Etwas kann in Bitmap verfügbar sein, aber extractAlpha macht es nicht, weil es die RGB-Werte der Farbe, die Sie an der Methode übergeben, nicht berücksichtigt (es sei denn, es ist einfach undokumentiert). Könnte einen Versuch wert sein. Ich werde es versuchen. – user432209

+0

Ich meinte nicht, dass es dein ganzes Problem lösen würde, nur dass es nützlich wäre. Wenn Sie die Dokumentation lesen, spricht es davon, sie mit drawCanvas zu kombinieren, um Farbinformationen einzugeben. –

+0

Wow, es hat funktioniert !!! Leider nur auf 2.2 und nicht 1.6. Ich habe seltsame Probleme mit 1.6, aber ich denke, das ist eine andere Frage. – user432209

1

Die Antwort, die für mich gearbeitet wurde eine aufzuschreiben Platz hier hat Transparent jpegs

Sie bieten ein schnelleres Code-Snippet für genau dies zu tun. Ich habe versucht, extractAlpha und es hat nicht funktioniert, aber Square's Lösung hat. Ändern Sie einfach ihre Lösung, um stattdessen das Farbbit und nicht das Alpha-Bit zu ändern.

heißt

pixels[x] = (pixels[x] & 0xFF000000) | (color & 0x00FFFFFF);