Zugriff auf Rohdaten in ARGB_8888 Android Bitmap

8

Ich versuche auf die Rohdaten einer Bitmap im ARGB_8888-Format auf Android zuzugreifen, indem ich die Methoden copyPixelsToBuffer und copyPixelsFromBuffer verwende. Der Aufruf dieser Aufrufe scheint jedoch immer den Alphakanal auf die RGB-Kanäle anzuwenden. Ich brauche die Rohdaten in einem Byte [] oder ähnlich (um JNI zu passieren; ja, ich weiß über Bitmap.h in Android 2.2, kann das nicht verwenden).

Hier ist ein Beispiel:

%Vor%

Das Protokoll zeigt dann

%Vor%

Ich verstehe, dass die Reihenfolge der Argb-Kanäle unterschiedlich ist; das ist gut. Aber ich nicht möchte, dass der Alphakanal auf jede Kopie angewendet wird (was es zu tun scheint).

Sollen copyPixelsToBuffer und copyPixelsFromBuffer funktionieren? Gibt es any Möglichkeit, um die Rohdaten in einem Byte []?

zu erhalten

Als Antwort auf die Antwort unten hinzugefügt:

Putting in buffer.order(ByteOrder.nativeOrder()); vor der copyPixelsToBuffer ändert das Ergebnis, aber immer noch nicht so, wie ich es will:

%Vor%

Scheint im Wesentlichen das gleiche Problem zu haben (Alpha wird auf jede copyPixelsFrom/ToBuffer angewendet).

    
Kasper Peeters 15.02.2011, 22:59
quelle

4 Antworten

1

Mir ist klar, dass dies sehr veraltet ist und dir wahrscheinlich jetzt nicht helfen wird, aber ich bin kürzlich auf dieses Problem gestoßen, als ich versucht habe, copyPixelsFromBuffer in meiner App zu verwenden. (Danke, dass du diese Frage gestellt hast, übrigens! Du hast mir viel Zeit beim Debuggen gespart.) Ich füge diese Antwort in der Hoffnung hinzu, dass es anderen wie mir hilft, vorwärts zu gehen ...

Obwohl ich dies noch nicht verwendet habe, um sicherzustellen, dass es funktioniert, sieht es so aus, dass wir ab API Level 19 endlich eine Möglichkeit haben, anzugeben, dass wir das Alpha (aka Premultiply) nicht innerhalb von% anwenden sollen. Code%. Sie fügen eine Bitmap -Methode hinzu, die in Situationen helfen sollte wie folgt, indem wir uns erlauben, setPremultiplied(boolean) anzugeben.

Ich hoffe, das hilft!

    
Turix 15.03.2014, 20:21
quelle
1

Ich nehme an, dass dies mit der Byte-Reihenfolge des von Ihnen verwendeten ByteBuffers zu tun haben könnte. ByteBuffer verwendet standardmäßig Big Endian. Setze Endianess auf den Puffer mit

%Vor%

Sehen Sie, ob es hilft.

Darüber hinaus ändert copyPixelsFromBuffer / copyPixelsToBuffer die Pixeldaten in keiner Weise. Sie werden roh kopiert.

    
misiu_mp 15.02.2011 23:17
quelle
1

Eine Möglichkeit, auf Daten in Bitmap zuzugreifen, ist die Methode getPixels (). Unten finden Sie ein Beispiel, das ich verwendet habe, um Graustufenbild von Argb Daten und dann zurück von Byte-Array zu Bitmap (natürlich, wenn Sie rgb benötigen Sie 3x Bytes reservieren und speichern Sie alle ...):

%Vor%     
Sami Varjo 23.10.2014 15:50
quelle
0

Dies ist eine alte Frage, aber ich kam zum selben Problem und fand heraus, dass das Bitmap-Byte vormultipliziert wurde. Sie können die Bitmap (ab API 19) so einstellen, dass der Puffer nicht vormultipliziert wird, aber In der API geben sie keine Garantie.

Von den Dokumenten :

  

public final void setPremultiplied(boolean premultiplied)

     

Legt fest, ob die Bitmap ihre Daten als vormultipliziert behandeln soll.   Bitmaps werden aus Performance-Gründen immer als vormultipliziert vom Ansichtssystem und Canvas behandelt. Das Speichern nicht vormultiplizierter Daten in einer Bitmap (über setPixel , setPixels oder BitmapFactory.Options.inPremultiplied ) kann zu einer falschen Überblendung führen, wenn sie vom Framework gezeichnet wird.

     

Diese Methode wirkt sich nicht auf das Verhalten einer Bitmap ohne Alphakanal aus, oder wenn hasAlpha() false zurückgibt.

     

Aufruf von createBitmap oder createScaledBitmap mit einer Quell-Bitmap, deren Farben nicht vormultipliziert sind, kann zu RuntimeException führen, da diese Funktionen das Zeichnen der Quelle erfordern, was für nicht vor-multiplizierte Bitmaps nicht unterstützt wird.

    
Ben Levi 19.08.2016 11:58
quelle