android – 捕获Camera2预览帧返回空缓冲区

我一直在研究一个简单的Android应用程序,旨在将Android Camera2 API管道中的流式相机帧传递给我的算法.我已经使用Android Camera1 API忠实地做了几个应用程序,但即使在检查(Google文档,论坛)以确认正确编码之后,我也无法从onImageAvailable()中的ImageReader捕获任何真实数据.请注意以下相关代码:

>设置ImageReaders:

private void setUpCameraOutputs(int width, int height) {

[....code....]

mImageReader = ImageReader.newInstance(smallestJPEG.getWidth(), 
                                       smallestJPEG.getHeight(),
                                       ImageFormat.JPEG, /*maxImages*/2);
// mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
mPreviewImageReader = ImageReader.newInstance(smallest.getWidth(), 
                                              smallest.getHeight(), 
                                              ImageFormat.YUV_420_888, 2);
mPreviewImageReader.setOnImageAvailableListener(mOnPreviewImageAvailableListener,
                                                mBackgroundHandler);

[....code....]

}

>设置CaptureSession:

private void createCameraPreviewSession() {
try {
    //Create Texture from Screen's TextureView
    SurfaceTexture texture = mTextureView.getSurfaceTexture();

    assert texture != null;

    //Configure Default Buffer Size
    texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

    //Create Output Surface from Texture
    Surface surface = new Surface(texture);

    // Set up a CaptureRequest.Builder with the output Surface.
    mPreviewRequestBuilder
            = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

    //Add Output Display surface
    mPreviewRequestBuilder.addTarget(surface);

    //Add Preview frame-grabbing surface 
    mPreviewRequestBuilder.addTarget(mPreviewImageReader.getSurface());

    mCameraDevice.createCaptureSession(Arrays.asList(surface, mPreviewImageReader.getSurface()),
            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. [...code...]
                        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                        // Flash is automatically enabled when necessary.
                        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

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

                @Override
                public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
                    [...code...]
                }
            }, null
    );
} catch (CameraAccessException e) {
    [...code...]
}
}

>设置OnImageAvailableListener:

private ImageReader mPreviewImageReader;
private final ImageReader.OnImageAvailableListener mOnPreviewImageAvailableListener
= new ImageReader.OnImageAvailableListener() {

@Override
public void onImageAvailable(ImageReader reader) {

    //Acquire Image, ByteBuffer, then byte array
    Image image = reader.acquireLatestImage();
    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    byte[] bytes = new byte[buffer.remaining()];

    //Check bytes array for anydata
    int cnt = 0;
    for (int i = 0; i < bytes.length; i++){
        if (bytes[i] != 0)cnt++;
    }
    Log.i(TAG, "cnt = " + cnt);
    image.close();

    //At this point, byte[] bytes is empty (all zero)
    [...code...]
}

};

在代码片段#3中,无论ImageReader格式如何,我的字节缓冲区始终返回空(全为零).有人有这个问题吗?我错过了任何代码吗?

解决方法:

add buffer.get(bytes); after byte [] bytes = new byte [buffer.remaining()];

上一篇:HTML框架IFrame结合JS在主页面和子页面间传值


下一篇:目标跟踪dlib+python