2

我想使用 ImageReader 中的图像字节数组来构造一个FirebaseVisionImageMetadata用于条形码扫描的对象(作为ML Kit的一部分)。我正在使用 Camera2 API 并遵循此 PR来支持帧预览。

Size sz = chooseOptimalSize();
mCallbackImageDataReader =
        ImageReader.newInstance(sz.getWidth(), sz.getHeight(), ImageFormat.YV12, 1);
    mCallbackImageDataReader.setOnImageAvailableListener(reader -> {
        byte[] data = getByteDataFromImageReader(reader);
        if (data != null) {
             //rotation compensation calculation not shown
            mCallback.onPreviewFrame(data, reader.getImageFormat(), reader.getWidth(), reader.getHeight(), rotationCompensation);
        }
    }, null);

@Nullable
private byte[] getByteDataFromImageReader(@NonNull ImageReader reader) {
    byte[] data = null;
    try (Image image = reader.acquireNextImage()) {
        Image.Plane[] planes = image.getPlanes();
        if (planes.length > 0) {
            ByteBuffer buffer = planes[0].getBuffer();
            data = new byte[buffer.remaining()];
            buffer.get(data);
        }
    }
    return data;
} 

但是,当我将结果格式传递给FirebaseVisionImageMetadata构建器时,我收到以下错误:

final FirebaseVisionImageMetadata meta = new FirebaseVisionImageMetadata.Builder()
        .setFormat(format) //exception thrown here
        .setWidth(width)
        .setHeight(height)
        .setRotation(rotation)
        .build();

java.lang.IllegalArgumentException
    at com.google.android.gms.common.internal.Preconditions.checkArgument(Unknown Source:5)
    at com.google.firebase.ml.vision.common.FirebaseVisionImageMetadata$Builder.setFormat(Unknown Source:13)

我传递给的格式ImageReaderImageReader.YV12sinceFirebaseVisionImageMetadata只接受NV21or YV12,但由于ImageReader不接受NV21,我只剩下YV12. 当我使用这种格式(如上所示)时,相机会以黑屏启动。我也尝试过传入ImageReader.YUV_420_888,但结果相同IllegalArgumentExceptionfrom FirebaseVisionImageMetadata

我的猜测是我可能必须以不同的方式转换字节数组,或者转换为不同的格式(?)。

任何帮助,将不胜感激。

资料来源:

  1. https://github.com/google/cameraview/pull/123/commits/f90580b1891c3edf91b4a254219d08b01110afce
  2. https://developer.android.com/reference/android/graphics/ImageFormat.html?hl=BG#YUV_420_888
4

1 回答 1

1

我想到了。我需要使用reader.acquireNextImage();

mCallbackImageDataReader.setOnImageAvailableListener(reader -> {
        try (Image image = reader.acquireNextImage())
        {
            if (image != null)
            {
                //compute rotationCompensation
                mCallback.onPreviewFrame(image, rotationCompensation);
            }
        }

    }, null);
于 2018-10-18T20:56:34.910 回答