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[]
当我在调用copyPixelsToBuffer
之后查看缓冲区时,字节都是0 ...从摄像机返回的位图是不可变的......但这应该无关紧要,因为它正在进行复制。
这段代码有什么问题?
答案 0 :(得分:601)
尝试这样的事情:
Bitmap bmp = intent.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bmp.recycle();
答案 1 :(得分:44)
CompressFormat太慢了......
尝试ByteBuffer。
※※※字节※※※的位图
width = bitmap.getWidth();
height = bitmap.getHeight();
int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(byteBuffer);
byteArray = byteBuffer.array();
※※※字节到位图※※※
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);
答案 2 :(得分:17)
您是否需要回放缓冲区?
此外,如果位图的步幅(以字节为单位)大于以像素为单位的行长度*字节/像素,则可能会发生这种情况。使字节长度为b.remaining()而不是size。
答案 3 :(得分:7)
使用以下函数将位图编码为byte [],反之亦然
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);
}
答案 4 :(得分:7)
这是Kotlin写的位图扩展.convertToByteArray
。
/**
* 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
}
答案 5 :(得分:6)
你的字节数组太小了。每个像素占用4个字节,而不仅仅是1个,因此将您的尺寸乘以* 4,以便阵列足够大。
答案 6 :(得分:2)
Ted Hopp是正确的,来自API文档:
public void copyPixelsToBuffer (Buffer dst)
“...此方法返回后,缓冲区的当前位置会更新:位置会增加缓冲区中写入的元素数。 “
和
public ByteBuffer get (byte[] dst, int dstOffset, int byteCount)
“从指定的字节数组中读取当前位置中的字节,从指定的偏移量开始,并按读取的字节数增加位置。”
答案 7 :(得分:2)
为了避免较大文件出现OutOfMemory
错误,我会通过将位图分成几个部分并合并它们的部分字节来解决任务。
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();
}
答案 8 :(得分:0)
尝试将其转换为String-Bitmap或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;
}
}
答案 9 :(得分:0)
我认为这样做 -
public static byte[] convertBitmapToByteArray(Bitmap bitmap){
ByteBuffer byteBuffer = ByteBuffer.allocate(bitmap.getByteCount());
bitmap.copyPixelsToBuffer(byteBuffer);
byteBuffer.rewind();
return byteBuffer.array();
}