【问题标题】:Android camera2 api. Setting multiple ImageReader surfaces gives blank output安卓camera2 api。设置多个 ImageReader 表面会产生空白输出
【发布时间】:2019-04-04 00:23:00
【问题描述】:

我有一个 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) 的三星 Galaxy S8 上进行测试

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

【问题讨论】:

    标签: android kotlin android-camera2


    【解决方案1】:

    ma​​xImages == 4 可能太多并耗尽您的 RAM。另外,不清楚您使用的是什么internalOutputFormat,以及它是否与largestPreview 尺寸兼容。

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

    从下面的 cmets 中,一个可行的解决方案:“错误本身并没有说太多 [...] 但是在搜索时,发现 JPEG 格式不支持多个表面。将其更改为YUV_420_888 完美运行。”

    【讨论】:

    • 感谢亚历克斯的快速回复。我将在原始帖子中添加有关所有这些的说明。 internalOutputFormatImageFormat.JPEG,我也尝试使用 ImageFormat.YUV_420_888,但结果相同。在这种情况下,maxImages = 4 也是安全的,因为我只在完成当前帧后才请求下一帧。如果我不使用另一个图像阅读器,则两个图像阅读器都可以单独工作。但加在一起只是空白屏幕。我想知道该设备是否相关。如果是这样,我正在使用 Android 8.0 测试 Samsung Galaxy S8
    • 正如 Alex 所说,您可以在捕获会话中添加多少同时输出是有限制的。会话创建或提交第一个捕获请求时应该有错误,因此请尝试检查是否有任何捕获错误报告给您的应用程序。或者,如果捕获会话创建返回错误回调。
    • @EddyTalvala 感谢您指出例外情况。错误本身并没有说太多Stream configuration failed due to: endConfigure:434,但经过搜索,发现JPEG格式不支持多个表面。将其更改为 YUV_420_888 后,它可以完美运行。
    • 是的,jpeg 是图像格式之王。我的意思是,捕获会话中可能只有一个 jpeg,或者没有。
    • 这个超级有用!我已将其中一些 cmets 编辑为答案,因为它为我解决了问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 2023-03-12
    • 2017-07-30
    • 2020-02-29
    • 1970-01-01
    相关资源
    最近更新 更多