Android - Lesen PNG-Bild ohne alpha-und entschlüsseln als ARGB_8888
Ich versuche zu Lesen ein Bild von der sdcard (im emulator) und dann erstellen Sie ein Bitmap-Bild mit der
BitmapFactory.decodeByteArray
Methode. Ich habe die Optionen:
options.inPrefferedConfig = Bitmap.Config.ARGB_8888
options.inDither = false
Dann extrahiere ich die Pixel in einen ByteBuffer.
ByteBuffer buffer = ByteBuffer.allocateDirect(width*height*4)
bitmap.copyPixelsToBuffer(buffer)
Ich diese ByteBuffer dann in das JNI, um es zu konvertieren in RGB-format und berechnen wollen, auf Sie.
Aber immer bekomme ich falsche Daten - I-test ohne änderung der ByteBuffer. Nur, was ich tun ist, um Sie in die native Methode in JNI. Dann warf Sie es in eine unsigned char*
auf und wandeln es wieder in eine ByteBuffer
bevor es wieder zurück nach Java.
unsigned char* buffer = (unsinged char*)(env->GetDirectBufferAddress(byteBuffer))
jobject returnByteBuffer = env->NewDirectByteBuffer(buffer, length)
Vor der Anzeige des Bildes bekomme ich die Daten wieder mit
bitmap.copyPixelsFromBuffer( buffer )
Aber dann hat er falsche Daten.
Meine Frage ist, ob dies ist, weil das Bild wird intern umgewandelt in RGB-565, oder was ist hier falsch?
.....
Haben eine Antwort für Sie:
->>> ja, es wird intern gewandelt zu RGB565.
Weiß jemand, wie man so ein bitmap-Bild aus PNG mit ARGB8888 pixel-format?
Wenn jemand eine Idee hat, wäre es toll!
- Der Punkt ist, dass ich müssen die Bild-Daten zu berechnen, auf die es in einer native-code-Teil. Für die Prüfung (emulator) ich nehme das PNG-Bild von SDcard und dann nehme ich Bild-Sequenz aus dem android-Kamera. Ich will 24Bit Bilder um keine Informationen zu verlieren, bevor die Berechnung drauf... PS: wo ist der commant von dem anderen Kerl gegangen?
- ok, ich werde versuchen einen anderen Weg. Ich will die Schnellste Weg, um die Bild-Daten aus einem Bild. Danach werde ich einige Bild-Verarbeitung auf die Rohdaten. Was ist der Schnellste Weg zum extrahieren der Bild-pixel-Daten in ein byte [] ? Grüße, F.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer ARGB_8888 Bitmap - (für pre-Honeycomb-Versionen) ist systemintern gespeichert in das RGBA-format.
So ist der alpha-Kanal bewegt am Ende. Sie sollten dies berücksichtigen, wenn der Zugriff auf ein Bitmap-Pixel nativ.
Ich nehme an, Sie sind das schreiben von code für eine Android-version niedriger als 3.2 (API level < 12), weil da ist dann das Verhalten der Methoden
geändert hat.
Auf älteren Plattformen (API level < 12) der BitmapFactory.decodeFile (..) - Methoden versuchen, wieder eine Bitmap mit RGB_565 config standardmäßig, wenn Sie nicht finden können alle alpha, das senkt die Qualität der bildreihen. Ist das noch ok, da kann man die Durchsetzung von ARGB_8888 bitmap mit
Das eigentliche problem kommt, wenn jedes pixel des Bildes hat einen alpha-Wert von 255 (d.h. vollständig deckend). In diesem Fall wird das Bitmap-flag 'hasAlpha' auf false gesetzt ist, auch wenn Ihr Bitmap hat ARGB_8888 config. Wenn Ihr *.png-Datei hatte wenigstens eine echte transparente pixel, dieses flag auf true festgelegt wurde, und Sie nicht haben, um nichts zu kümmern.
Also, wenn Sie wollen, erstellen Sie eine Bitmap skaliert mit
die Methode überprüft, ob die 'hasAlpha' - flag ist auf true oder false gesetzt, und in Ihrem Fall ist es auf false gesetzt, werden die Ergebnisse bei der Erlangung einer skalierten Bitmap, die automatisch konvertiert die RGB_565 format.
Daher auf API-Ebene >= 12 es gibt eine öffentliche Methode namens
hätte dieses Problem gelöst. Bisher war dies nur eine Erklärung für das problem.
Ich habe einige nachforschungen und festgestellt, dass die setHasAlpha Methode hat für eine lange Zeit bestanden, und es ist öffentlich, aber versteckt wurde (@hide annotation). Hier ist, wie es definiert ist, auf Android 2.3:
Hier ist nun mein Lösungsvorschlag. Sie ist nicht mit dem kopieren der bitmap-Daten:
Überprüft zur Laufzeit mit java.lang.Widerspiegeln, wenn der aktuelle
Bitmap-Implementierung hat eine öffentliche "setHasAplha' - Methode.
(Nach meinen tests funktioniert es einwandfrei seit API-level 3 und habe ich noch nicht getestet niedrigeren Versionen, weil JNI nicht funktionieren würde). Sie haben möglicherweise Probleme, wenn ein Hersteller explizit gemacht, es als privat, geschützt oder gelöscht.
Nennen sich die "setHasAlpha' Methode für eine gegebene Bitmap-Objekt mittels JNI.
Das funktioniert perfekt, auch für private Methoden oder Felder. Nun ist es offiziell, dass JNI nicht prüfen, ob Sie gegen die access-control-Regeln oder nicht.
Quelle: http://java.sun.com/docs/books/jni/html/pitfalls.html (10.9)
Das gibt uns große Kraft, die sollten sinnvoll genutzt werden. Ich würde nicht versuchen, ändern eine Letzte Feld, selbst wenn es funktionieren würde (nur um ein Beispiel zu geben). Und bitte beachten: dies ist nur ein workaround...
Hier ist meine Umsetzung aller erforderlichen Methoden:
JAVA-TEIL:
Laden Sie Ihre lib und deklariert die native Methode:
Nativen Abschnitt ('jni' Ordner)
Android.mk:
bitmapUtils.c:
Das ist es. Wir sind fertig. Ich habe den gesamten code für copy-and-paste-Zwecke.
Der eigentliche code ist nicht groß, aber alle diese paranoid Fehler überprüft, macht es viel größer ist. Ich hoffe, dass dies hilfreich sein könnte für jedermann.