首页 文章

将Java位图转换为字节数组

提问于
浏览
245
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 ...从摄像机返回的位图是不可变的...但是不应该't matter since it'进行复制 .

这段代码有什么问题?

9 回答

  • 2

    这是位图扩展 .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
    }
    
  • 5

    你的字节数组太小了 . 每个像素占用4个字节,而不仅仅是1个,因此将您的大小* 4乘以使阵列足够大 .

  • 6

    你需要倒回缓冲区吗?

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

  • 590

    Ted Hopp是正确的,来自API文档:

    public void copyPixelsToBuffer (Buffer dst)
    

    “...此方法返回后,缓冲区的当前位置会更新:位置会增加缓冲区中写入的元素数 . ”

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

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

  • 6

    尝试这样的事情:

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

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

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

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

相关问题