代码之家  ›  专栏  ›  技术社区  ›  Sonhja

如何使用ByteBuffer将位图图像保存在本机内存中并恢复

  •  1
  • Sonhja  · 技术社区  · 9 年前

    我正在从摄像机获取直接流,我需要保存一个 Bitmap 进入 ByteBuffer 并恢复它。这是我的代码:

    YuvImage yuv = new YuvImage(data.getExtractImageData(), previewFormat, width, height, null);
    
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuv.compressToJpeg(new Rect(0, 0, width, height), 50, out);
    
        byte[] bytes = out.toByteArray();
    
        Bitmap image = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    
        Bitmap imageResult = RotateImage(image, 4 - rotation);
        imageResult = cropBitmap(imageResult, data.getRect());
    
        int nBytes = imageResult.getByteCount();
        ByteBuffer buffer = ByteBuffer.allocateDirect(nBytes);
        imageResult.copyPixelsToBuffer(buffer);
    
        return buffer.array();
    

    要转换的代码 byte[] 返回到 位图 :

    Bitmap bitmap = BitmapFactory.decodeByteArray(images.getImage(), 0, images.getImage().length);
    

    但是, bitmap 转换后为Null。。。

    知道怎么了吗?

    澄清:我需要保存 byte[] image 在本机内存中,这就是为什么我要 ByteBuffer.allocateDirect 。我需要在特定点裁剪图像,这就是为什么我需要 位图 .

    2 回复  |  直到 9 年前
        1
  •  1
  •   samgak    9 年前

    decodeByteArray() 解码存储在字节阵列中的压缩图像(例如JPEG或PNG)。然而 copyPixelsToBuffer() 将位图的内容“原样”(即未压缩)复制到字节缓冲区中,因此无法通过decodeByteArray()对其进行解码。

    如果不想重新编码位图,可以像现在这样使用copyPixelsToBuffer(),然后更改第二个代码块以使用 copyPixelsFromBuffer() 而不是decodeByteArray()。

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    bitmap.copyPixelsFromBuffer(ByteBuffer.wrap(images.getImage()));
    

    您需要保存宽度和高度。还要确保 Bitmap.Config 是相同的。

    基本上,如果您将其保存为压缩文件,则必须加载压缩文件,如果您保存为未压缩文件,那么必须加载未压缩文件。

        2
  •  0
  •   Droid Teahouse    6 年前

    分配缓冲区时还应该设置字节顺序,因为Java是大端序,因此默认情况下缓冲区是大端,android是小端序,而底层cpu架构可能会有所不同,但大多数是小端的wrt android:

    buffer.order( ByteOrder.nativeOrder() );