L'accès aux données brutes en ARGB_8888 Android Bitmap
Je suis en train d'accéder aux données brutes d'une image Bitmap dans ARGB_8888 format sur Android, à l'aide de la copyPixelsToBuffer
et copyPixelsFromBuffer
méthodes. Cependant, l'invocation de ces appels semble toujours appliquer le canal alpha pour les canaux rvb. J'ai besoin des données brutes dans un byte[] ou similaire (pour passer à travers JNI, oui, je sais à propos de bitmap.h en Android 2.2, ne peut pas l'utiliser).
Voici un exemple:
//Create 1x1 Bitmap with alpha channel, 8 bits per channel
Bitmap one = Bitmap.createBitmap(1,1,Bitmap.Config.ARGB_8888);
one.setPixel(0,0,0xef234567);
Log.v("?","hasAlpha() = "+Boolean.toString(one.hasAlpha()));
Log.v("?","pixel before = "+Integer.toHexString(one.getPixel(0,0)));
//Copy Bitmap to buffer
byte[] store = new byte[4];
ByteBuffer buffer = ByteBuffer.wrap(store);
one.copyPixelsToBuffer(buffer);
//Change value of the pixel
int value=buffer.getInt(0);
Log.v("?", "value before = "+Integer.toHexString(value));
value = (value >> 8) | 0xffffff00;
buffer.putInt(0, value);
value=buffer.getInt(0);
Log.v("?", "value after = "+Integer.toHexString(value));
//Copy buffer back to Bitmap
buffer.position(0);
one.copyPixelsFromBuffer(buffer);
Log.v("?","pixel after = "+Integer.toHexString(one.getPixel(0,0)));
Le journal montre ensuite
hasAlpha() = true
pixel before = ef234567
value before = 214161ef
value after = ffffff61
pixel after = 619e9e9e
Je comprends que l'ordre de l'argb canaux est différent; c'est bien. Mais je n'ai pas
voulez le canal alpha à être appliqué sur chaque exemplaire (qui est ce qu'il semble être en train de faire).
Est-ce de cette manière copyPixelsToBuffer
et copyPixelsFromBuffer
sont censés travailler? Est-il tout façon d'obtenir les données brutes dans un byte[]?
Ajouté en réponse à la réponse ci-dessous:
La mise en buffer.order(ByteOrder.nativeOrder());
avant la copyPixelsToBuffer
ne change pas le résultat, mais pas encore dans la façon dont je le veux:
pixel before = ef234567
value before = ef614121
value after = ffffff41
pixel after = ff41ffff
Semble souffrir de essentiellement le même problème (alpha appliquée sur chaque copyPixelsFrom/ToBuffer
).
Vous pourriez vouloir vérifier
Bitmap.isPremultiplied()
trop. Suppose qu'il est défini à true
par défaut lors de canal alpha est présent.Avez-vous essayé
Bitmap.getPixels()
? La documentation dit explicitement qu'il renvoie unpremultiplied ARGB pixels. Il y a aussi une réponse à ce sujet getPixels()
ci-dessous, mais vous n'avez pas à le commenter.
OriginalL'auteur Kasper Peeters | 2011-02-15
Vous devez vous connecter pour publier un commentaire.
Je réalise que c'est très fade et ne sera probablement pas vous aider maintenant, mais je suis tombé sur cette récemment en essayant d'obtenir
copyPixelsFromBuffer
à travailler dans mon application. (Merci de poser cette question, btw! Tu me sauve des tonnes de temps dans le débogage.) Je suis l'ajout de cette réponse, dans l'espoir qu'il aide les autres comme moi aller de l'avant...Bien que je n'ai pas utilisé encore pour vous assurer qu'il fonctionne, il semble que, comme de l'API de Niveau 19, nous allons enfin avoir un moyen de spécifier de ne pas "appliquer l'alpha" (un.k.un. prémultiplier) dans
Bitmap
. Ils sont l'ajout d'unsetPremultiplied(boolean)
méthode qui devraient vous aider dans des situations de ce genre à l'avenir, en nous permettant de spécifierfalse
.J'espère que cela aide!
hehe, merci! J' j'espère cette solution à nos problèmes!
OriginalL'auteur Turix
Ma conjecture est que cela pourrait avoir à faire avec l'ordre des octets de l'ByteBuffer vous utilisez. ByteBuffer utilise big endian par défaut.
Ensemble endianess sur le tampon avec
Voir si ça aide.
En outre, copyPixelsFromBuffer/copyPixelsToBuffer ne change pas les données de pixels d'une quelconque façon. Ils sont copiés raw.
En effet, copyPixelsToBuffer semble être l'application de la couche alpha sur les canaux rvb. Cela peut être vu clairement lorsque vous setPixel(0,0. 0x7f224466) - ce sera 0x7f332211 lors de la lecture dans le tampon. Ce peut-être un bug. Envisager de produire une déclaration.
OriginalL'auteur misiu_mp
Un chemin pour accéder aux données d'image Bitmap est d'utiliser getPixels() la méthode. Vous trouverez ci-dessous un exemple que j'ai utilisé pour obtenir des niveaux de gris de l'image de argb de données, puis de retour à partir du tableau d'octets Bitmap (bien sûr, si vous avez besoin d'rvb vous réserve 3x octets et les sauver tous...):
OriginalL'auteur Sami Varjo
C'est une vieille question, mais j'ai eu le même problème, et trouvé que l'image de l'octet sont pré-multiplié, vous pouvez définir l'image bitmap (comme d'API 19), afin de ne pas pré-multiplier le tampon, mais dans l'API, ils ne font aucune garantie.
De les docs:
OriginalL'auteur Ben Levi