Bitmap bmp = intent.getExtras().get("data"); int size = bmp.getRowBytes() * bmp.getHeight(); ByteBuffer b = ByteBuffer.allocate(size); bmp.copyPixelsToBuffer(b); byte[] bytes = new byte[size]; try { b.get(bytes, 0, bytes.length); } catch (BufferUnderflowException e) { // always happens } // do something with byte[]
Quand je regarde le tampon après l’appel à copyPixelsToBuffer
les octets sont tous à 0 … Le bitmap renvoyé par la caméra est immuable … mais cela ne devrait pas avoir d’importance car il fait une copie.
Quel pourrait être le problème avec ce code?
Essayez quelque chose comme ça:
Bitmap bmp = intent.getExtras().get("data"); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); bmp.recycle();
Utiliser CompressFormat est trop lent …
Essayez d’utiliser ByteBuffer.
Map Bitmap to byte ※※※
width = bitmap.getWidth(); height = bitmap.getHeight(); int size = bitmap.getRowBytes() * bitmap.getHeight(); ByteBuffer byteBuffer = ByteBuffer.allocate(size); bitmap.copyPixelsToBuffer(byteBuffer); byteArray = byteBuffer.array();
Te octet à bitmap ※※※
Bitmap.Config configBmp = Bitmap.Config.valueOf(bitmap.getConfig().name()); Bitmap bitmap_tmp = Bitmap.createBitmap(width, height, configBmp); ByteBuffer buffer = ByteBuffer.wrap(byteArray); bitmap_tmp.copyPixelsFromBuffer(buffer);
Avez-vous besoin de rembobiner le tampon, peut-être?
En outre, cela peut se produire si la longueur de la bitmap (en octets) est supérieure à la longueur de la ligne en pixels * octets / pixel. Définissez la longueur des octets b.remaining () au lieu de la taille.
Votre tableau d’octets est trop petit. Chaque pixel occupe 4 octets, pas seulement 1, donc multipliez votre taille * 4 pour que le tableau soit assez grand.
Utilisez les fonctions ci-dessous pour encoder les bitmap en octets [] et vice versa
public static Ssortingng encodeTobase64(Bitmap image) { Bitmap immagex = image; ByteArrayOutputStream baos = new ByteArrayOutputStream(); immagex.compress(Bitmap.CompressFormat.PNG, 90, baos); byte[] b = baos.toByteArray(); Ssortingng imageEncoded = Base64.encodeToSsortingng(b, Base64.DEFAULT); return imageEncoded; } public static Bitmap decodeBase64(Ssortingng input) { byte[] decodedByte = Base64.decode(input, 0); return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length); }
Afin d’éviter l’erreur OutOfMemory
pour les fichiers plus volumineux, je résoudrais la tâche en divisant un bitmap en plusieurs parties et en fusionnant les octets de leurs parties.
private byte[] getBitmapBytes(Bitmap bitmap) { int chunkNumbers = 10; int bitmapSize = bitmap.getRowBytes() * bitmap.getHeight(); byte[] imageBytes = new byte[bitmapSize]; int rows, cols; int chunkHeight, chunkWidth; rows = cols = (int) Math.sqrt(chunkNumbers); chunkHeight = bitmap.getHeight() / rows; chunkWidth = bitmap.getWidth() / cols; int yCoord = 0; int bitmapsSizes = 0; for (int x = 0; x < rows; x++) { int xCoord = 0; for (int y = 0; y < cols; y++) { Bitmap bitmapChunk = Bitmap.createBitmap(bitmap, xCoord, yCoord, chunkWidth, chunkHeight); byte[] bitmapArray = getBytesFromBitmapChunk(bitmapChunk); System.arraycopy(bitmapArray, 0, imageBytes, bitmapsSizes, bitmapArray.length); bitmapsSizes = bitmapsSizes + bitmapArray.length; xCoord += chunkWidth; bitmapChunk.recycle(); bitmapChunk = null; } yCoord += chunkHeight; } return imageBytes; } private byte[] getBytesFromBitmapChunk(Bitmap bitmap) { int bitmapSize = bitmap.getRowBytes() * bitmap.getHeight(); ByteBuffer byteBuffer = ByteBuffer.allocate(bitmapSize); bitmap.copyPixelsToBuffer(byteBuffer); byteBuffer.rewind(); return byteBuffer.array(); }
Voici l’extension bitmap .convertToByteArray
écrite dans Kotlin.
/** * Convert bitmap to byte array using ByteBuffer. */ fun Bitmap.convertToByteArray(): ByteArray { //minimum number of bytes that can be used to store this bitmap's pixels val size = this.byteCount //allocate new instances which will hold bitmap val buffer = ByteBuffer.allocate(size) val bytes = ByteArray(size) //copy the bitmap's pixels into the specified buffer this.copyPixelsToBuffer(buffer) //rewinds buffer (buffer position is set to zero and the mark is discarded) buffer.rewind() //transfer bytes from buffer into the given destination array buffer.get(bytes) //return bitmap's pixels return bytes }
Ted Hopp a raison de l’API Documentation:
public void copyPixelsToBuffer (Buffer dst)
“… Après le retour de cette méthode, la position actuelle du tampon est mise à jour: la position est incrémentée du nombre d’éléments écrits dans le tampon.”
et
public ByteBuffer get (byte[] dst, int dstOffset, int byteCount)
“Lit les octets de la position actuelle dans le tableau d’octets spécifié, en commençant au décalage spécifié, et augmente la position par le nombre d’octets lus.”
Essayez ceci pour convertir Ssortingng-Bitmap ou Bitmap-Ssortingng
/** * @param bitmap * @return converting bitmap and return a ssortingng */ public static Ssortingng BitMapToSsortingng(Bitmap bitmap){ ByteArrayOutputStream baos=new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG,100, baos); byte [] b=baos.toByteArray(); Ssortingng temp=Base64.encodeToSsortingng(b, Base64.DEFAULT); return temp; } /** * @param encodedSsortingng * @return bitmap (from given ssortingng) */ public static Bitmap SsortingngToBitMap(Ssortingng encodedSsortingng){ try{ byte [] encodeByte=Base64.decode(encodedSsortingng,Base64.DEFAULT); Bitmap bitmap= BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length); return bitmap; }catch(Exception e){ e.getMessage(); return null; } }