Android camera2 API。设置多个ImageReader曲面可提供空白输出

时间:2018-11-14 20:37:10

标签: android kotlin android-camera2

我有一个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")
}

ImageReaders的初始化是这样的。

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) }
}

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

  • internalOutput的格式为ImageFormat.JPEGImageFormat.YUV_420_888
  • 图像尺寸基于最佳尺寸
  • 这对任何一个图像读取器都可以很好地工作,但是当我将两者都加在一起时,就会出现空白屏幕!
  • 使用Android Oreo(8.0)在Samsung Galaxy S8上进行测试

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

1 个答案:

答案 0 :(得分:2)

maxImages == 4 可能太多,并耗尽了RAM。另外,不清楚您使用什么 internalOutputFormat ,以及它是否与 largestPreview 大小兼容。

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

从下面的评论中,一个有效的解决方案:“该错误本身说的并不多,但是在搜索时发现JPEG格式不支持多个表面。将其更改为YUV_420_888它可以完美工作。”