BitmapFactory.getByteArray 仅当字节数组来自存储时才有效

BitmapFactory.getByteArray only works if the byte array come from storage

我正在尝试创建一个程序来直接处理来自 Camera2 预览的图像,但在实际处理传入图像时我一直 运行 遇到问题。

在我的 OnImageAvailableListener.onImageAvailable() 回调中,我得到了一个 ImageReader 对象,我从中 acquireNextImage() 并将该 Image 对象传递到我的辅助函数中。从那里,我将它转换成一个字节数组,并尝试进行处理。相反,每次我到达将其转换为 Bitmap 的部分时,BitmapFactory.getByteArray returns null,即使字节数组是格式正确的 JPEG。

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
        = new ImageReader.OnImageAvailableListener() {
    @Override
    public void onImageAvailable(ImageReader imageReader) {
        Image image = imageReader.acquireNextImage();
        ProcessBarcode(image);
        image.close();
    }
};

private void ProcessBarcode(Image image) {
    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    int bufferSize = buffer.remaining();
    byte[] bytes = new byte[bufferSize];
    buffer.get(bytes);

    FileOutputStream output = null;
    try {
        output = new FileOutputStream(mFile);
        output.write(bytes);
        output.close();
    } catch (IOException e) {
        // Do something clever
    }

    // This call FAILS
    //Bitmap b = BitmapFactory.decodeByteArray(bytes, 0, buffer.remaining(), o);

    // But this call WORKS?
    Bitmap b = BitmapFactory.decodeFile(mFile.getAbsolutePath());

    detector = new BarcodeDetector.Builder(getActivity())
            .setBarcodeFormats(Barcode.EAN_13 | Barcode.ISBN)
            .build();

    if (b != null) {
        Frame isbnFrame = new Frame.Builder().setBitmap(b).build();
        SparseArray<Barcode> barcodes = detector.detect(isbnFrame);

        if (barcodes.size() != 0) {
            Log.d("Barcode decoded: ",barcodes.valueAt(0).displayValue);
        }
        else {
            Log.d(TAG, "No barcode detected");
        }
    }
    else {
        Log.d(TAG, "No bitmap detected");
    }
}

ImageReader 设置如下:

mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);

基本上我看到的是,如果我直接使用字节数组而不先将其保存到内部存储器,相机预览快速而活泼,虽然 Bitmap 始终为 null 所以我不是实际上执行任何处理。如果我将字节数组保存到内存中,那么我可能会得到 2-3fps,但处理工作如我所愿。

在调用 buffer.get(bytes) 之后,buffer.remaining() 将 return 0,因为您刚刚读取了整个 ByteBuffer。 remaining() 告诉您当前位置和缓冲区限制之间还剩下多少字节,然后调用 get() 将位置向前移动读取的字节数。

因此,当您执行 decodeByteArray(bytes,0, buffer.remaining(), 0) 时,您实际上并没有解码任何字节。

如果您尝试 decodeByteArray(bytes, 0, bytes.length, 0),是否有效?