convirtiendo el bitmap de Java en una matriz de bytes

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[] 

Cuando miro el búfer después de la llamada a copyPixelsToBuffer los bytes son todos 0 … El bitmap devuelto por la cámara es inmutable … pero eso no debería importar ya que está haciendo una copia.

¿Qué podría estar mal con este código?

Pruebe algo como esto:

 Bitmap bmp = intent.getExtras().get("data"); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); bmp.recycle(); 

Usar CompressFormat es demasiado lento …

Intenta usar ByteBuffer.

※※※ Mapa de bits a byte ※※※

  width = bitmap.getWidth(); height = bitmap.getHeight(); int size = bitmap.getRowBytes() * bitmap.getHeight(); ByteBuffer byteBuffer = ByteBuffer.allocate(size); bitmap.copyPixelsToBuffer(byteBuffer); byteArray = byteBuffer.array(); 

※※※ byte a 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); 

¿Necesitas rebobinar el buffer, quizás?

Además, esto podría suceder si la zancada (en bytes) del bitmap es mayor que la longitud de la fila en píxeles * bytes / píxel. Haga que la longitud de los bytes b.remaining () en lugar de tamaño.

Su matriz de bytes es demasiado pequeña. Cada píxel ocupa 4 bytes, no solo 1, así que multiplique su tamaño * 4 para que la matriz sea lo suficientemente grande.

Use las funciones siguientes para codificar bitmap en byte [] y viceversa

 public static String encodeTobase64(Bitmap image) { Bitmap immagex = image; ByteArrayOutputStream baos = new ByteArrayOutputStream(); immagex.compress(Bitmap.CompressFormat.PNG, 90, baos); byte[] b = baos.toByteArray(); String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT); return imageEncoded; } public static Bitmap decodeBase64(String input) { byte[] decodedByte = Base64.decode(input, 0); return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length); } 

Para evitar el error de OutOfMemory para archivos más grandes, resolvía la tarea dividiendo un bitmap en varias partes y fusionando los bytes de sus partes.

 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(); } 

Aquí está la extensión de bitmap .convertToByteArray escribió en 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 está en lo cierto, de la Documentación API:

 public void copyPixelsToBuffer (Buffer dst) 

“… Después de que este método regrese, la posición actual del búfer se actualiza: la posición se incrementa por la cantidad de elementos escritos en el búfer”.

y

 public ByteBuffer get (byte[] dst, int dstOffset, int byteCount) 

“Lee bytes desde la posición actual en la matriz de bytes especificada, comenzando en el desplazamiento especificado, y aumenta la posición por el número de bytes leídos”.

Intenta esto para convertir String-Bitmap o Bitmap-String

 /** * @param bitmap * @return converting bitmap and return a string */ public static String BitMapToString(Bitmap bitmap){ ByteArrayOutputStream baos=new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG,100, baos); byte [] b=baos.toByteArray(); String temp=Base64.encodeToString(b, Base64.DEFAULT); return temp; } /** * @param encodedString * @return bitmap (from given string) */ public static Bitmap StringToBitMap(String encodedString){ try{ byte [] encodeByte=Base64.decode(encodedString,Base64.DEFAULT); Bitmap bitmap= BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length); return bitmap; }catch(Exception e){ e.getMessage(); return null; } }