Android 相机 2 api。设置多个 ImageReader 表面会产生空白输出

Android camera2 api. Setting multiple ImageReader surfaces gives blank output

我有一个 camera2 实现。当前的设置是,它使用纹理视图表面来显示实际的相机视图,并使用 ImageReader 表面来捕获图像。

现在我也想捕捉预览帧。所以我尝试添加一个新的 ImageReader 表面来捕捉帧。但是当我将该表面添加到 createCaptureSession 请求时,屏幕变为空白。可能有什么问题?下面是我用来将曲面添加到 createCaptureSession

的代码
val surface = preview.surface
            ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

val previewIRSurface = previewImageReader?.surface
            ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

val captureSurface = captureImageReader?.surface
            ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

try {
    val template = if (zsl) CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG else CameraDevice.TEMPLATE_PREVIEW

    previewRequestBuilder = camera?.createCaptureRequest(template)
            ?.apply { addTarget(surface) }
            ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

    val surfaces: ArrayList<Surface> = arrayListOf(surface, previewIRSurface, captureSurface)

    camera?.createCaptureSession(surfaces, sessionCallback, backgroundHandler)

} catch (e: CameraAccessException) {
    throw RuntimeException("Failed to start camera session")
}

ImageReader的初始化是这样的

private fun prepareImageReaders() {

    val largestPreview = previewSizes.sizes(aspectRatio).last()

    previewImageReader?.close()

    previewImageReader = ImageReader.newInstance(
            largestPreview.width,
            largestPreview.height,
            internalOutputFormat,
            4 // maxImages
    ).apply { setOnImageAvailableListener(onPreviewImageAvailableListener, backgroundHandler) }

    val largestPicture = pictureSizes.sizes(aspectRatio).last()

    captureImageReader?.close()

    captureImageReader = ImageReader.newInstance(
            largestPicture.width,
            largestPicture.height,
            internalOutputFormat,
            2 // maxImages
    ).apply { setOnImageAvailableListener(onCaptureImageAvailableListener, backgroundHandler) }
}

关于上面使用的参数的更多说明:

原代码在这里https://github.com/pvasa/cameraview-ex/blob/development/cameraViewEx/src/main/api21/com/priyankvasa/android/cameraviewex/Camera2.kt

maxImages == 4 可能太多了,会耗尽您的 RAM。另外,不清楚你用的是什么internalOutputFormat,是否兼容largestPreview尺寸。

最重要的是,研究 createCaptureSession() 支持的表面列表参数的长表列表。根据您的相机功能,您使用的三个表面可能太多了。

根据下面的评论,一个可行的解决方案:"The error itself doesn't say much [...] but upon searching, it is found that multiple surfaces are not supported for JPEG format. Upon changing it to YUV_420_888 it works flawlessly."