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

How to save Bitmap image in Native memory using ByteBuffer and recover it

我正在从相机获取直接流,我需要将 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 bitmap = BitmapFactory.decodeByteArray(images.getImage(), 0, images.getImage().length);

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

知道哪里出了问题吗?

澄清一下:我需要将 byte[] image 保存在本机内存中,这就是我执行 ByteBuffer.allocateDirect 的原因。我需要在特定点裁剪图像,这就是为什么我需要 bitmap.

decodeByteArray() decodes a compressed image (e.g. a JPEG or PNG) stored in a byte array. However copyPixelsToBuffer() 将 Bitmap 的内容复制到字节缓冲区 "as is"(即未压缩),因此无法通过 decodeByteArray() 进行解码。

如果您不想重新编码您的位图,您可以像现在一样使用 copyPixelsToBuffer(),并将您的第二个代码块更改为使用 copyPixelsFromBuffer() 而不是 decodeByteArray()。

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

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

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

分配缓冲区时还应设置字节顺序,因为Java是大端,因此缓冲区默认是大端,android是小端,底层cpu 体系结构可能会有所不同,但大多是小端 wrt android:

buffer.order( ByteOrder.nativeOrder() );