Android Camera2,我从ImageReader 获取YUV 图像。 U 和 V 缓冲区只有一行(跨步)数据,其余为零

Android Camera2, I aquire YUV image from ImageReader. U and V buffers have only one row(stride) data, the rest is zero

这就是我实例化 ImageReader 的方式。

Size[] sizes = configs.getOutputSizes(ImageFormat.YUV_420_888);
        mImageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, 2);

        mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);

        Surface rgbCaptureSurface = mImageReader.getSurface();
        List<Surface> surfaces = new ArrayList<Surface>();
        surfaces.add(rgbCaptureSurface);

        //surfaces.add(surface);

        mPreviewRequestBuilder
                = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        //mPreviewRequestBuilder.addTarget(surface);

        mPreviewRequestBuilder.addTarget(rgbCaptureSurface);

        mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {


            @Override
            public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                // The camera is already closed
                if (null == mCameraDevice) {
                    return;
                }

                // When the session is ready, we start displaying the preview.
                mCaptureSession = cameraCaptureSession;
                try {
                    // Auto focus should be continuous for camera preview.
                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                            CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);

                    // Flash is automatically enabled when necessary.
                    //setAutoFlash(mPreviewRequestBuilder);

                    // Finally, we start displaying the camera preview.
                    mPreviewRequest = mPreviewRequestBuilder.build();
                    mCaptureSession.setRepeatingRequest(mPreviewRequest,
                            mCaptureCallback, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

阅读是这样进行的:

  public void onImageAvailable(ImageReader reader) {
        Image image;
        while (true) {
            image = reader.acquireLatestImage();

            if (image == null) return;


            Image.Plane Y = image.getPlanes()[0];
            Image.Plane U = image.getPlanes()[1];
            Image.Plane V = image.getPlanes()[2];

            int Yb = Y.getBuffer().remaining();
            int Ub = U.getBuffer().remaining();
            int Vb = V.getBuffer().remaining();

            byte[] data = new byte[Yb + Ub + Vb];


            Y.getBuffer().get(data, 0, Yb);
            U.getBuffer().get(data, Yb, Ub);
            V.getBuffer().get(data, Yb + Ub, Vb);

我尝试了几种不同的图像格式。我在 LG G3 上测试,API 21 和问题 occurs.On Nexus 4 我没有问题,API 22.

我升级到 API 23,同样的代码工作正常。还在 API 22 上进行了测试,它也有效。

同于:

您的观察是正确的。 API 21 不正确支持 Camera2。这已经被几个人在 SO 上独立发现,例如参见Camera2 API21 not working

所以在API22之前开始使用Camera2是合理的。无法理解为何在此期间没有修改文档。

就我个人而言,我将继续进行 Camera2 研究,但我现在仍然不愿意在我的应用程序中使用 Camera2。我首先想先在很多设备上测试它,在不久的将来,我不希望 "Camera1" 不再被新设备支持。