将Java位图转换为字节数组

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 …从相机返回的位图是不可变的,但这不应该因为它正在进行复制。

这段代码有什么问题?

尝试这样的事情:

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

使用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); 

你是否需要倒带缓冲区,也许?

此外,如果位图的步长(以字节为单位)大于以像素*字节/像素为单位的行长度,则可能会发生这种情况。 使字节长度为b.remaining()而不是大小。

你的字节数组太小了。 每个像素占用4个字节,而不仅仅是1个,所以要乘以你的大小* 4,以便数组足够大。

使用下面的函数将位图编码为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); } 

为了避免更大的文件的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(); } 

Ted Hopp是正确的,从API文档:

 public void copyPixelsToBuffer (Buffer dst) 

“…在此方法返回后,缓冲区的当前位置将被更新:位置将增加缓冲区中写入的元素的数量。

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

“从当前位置读取字节到指定的字节数组中,从指定的偏移量开始,并按读取的字节数增加位置”。

这里是位图扩展名.convertToByteArray在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 } 

试试这个来转换字符串位图或位图字符串

 /** * @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; } }