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[]
When I look at the buffer after the call to copyPixelsToBuffer
the bytes are all 0... The bitmap returned from the camera is immutable... but that shouldn't matter since it's doing a copy.
What could be wrong with this code?
This question is related to
java
android
serialization
bitmap
bytebuffer
CompressFormat is too slow...
Try ByteBuffer.
???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();
???byte to 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);
Your byte array is too small. Each pixel takes up 4 bytes, not just 1, so multiply your size * 4 so that the array is big enough.
Try this to convert String-Bitmap or 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;
}
}
In order to avoid OutOfMemory
error for bigger files, I would solve the task by splitting a bitmap into several parts and merging their parts' bytes.
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();
}
Ted Hopp is correct, from the API Documentation :
public void copyPixelsToBuffer (Buffer dst)
"... After this method returns, the current position of the buffer is updated: the position is incremented by the number of elements written in the buffer. "
and
public ByteBuffer get (byte[] dst, int dstOffset, int byteCount)
"Reads bytes from the current position into the specified byte array, starting at the specified offset, and increases the position by the number of bytes read."
Use below functions to encode bitmap into byte[] and vice versa
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);
}
Here is bitmap extension .convertToByteArray
wrote in 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
}
Do you need to rewind the buffer, perhaps?
Also, this might happen if the stride (in bytes) of the bitmap is greater than the row length in pixels * bytes/pixel. Make the length of bytes b.remaining() instead of size.
Source: Stackoverflow.com