Android Camera2 拍摄图像倾斜

Android Camera2 capture image skewed

更新:这看起来与此有关: - 我认为这是一个错误,因为 Nexus 5/6 工作正常并且没有意义需要获得完整的传感器尺寸,然后手动裁剪以达到所需的纵横比,还不如不使用 "supported" 输出尺寸!

问题:

  1. 使用 Camera2 API 获取相机的特征,并提取适合 MediaCodec.class
  2. 的输出尺寸
  3. 创建具有合适相机输出尺寸之一的 MediaCodec 输入表面。将输出提供给某些 MediaMuxer 或其他任何东西,以查看输出。
  4. 使用编解码器创建的表面作为目标开始相机捕获请求。
  5. 编解码器输出的大小正确。但结果因设备而异:

    • Nexus 5/6:Android 5/6 一切正常。
    • Samsung tablet with Android 5.1:对于某些分辨率,图像有明显的拉伸,说明相机输出分辨率与表面尺寸不匹配。当开始旋转相机时变得非常明显 - 图像变得越来越倾斜,因为它没有与 X/Y 轴对齐。对于其他一些分辨率,输出正常。这里没有与大小或纵横比相关的模式。

没问题,有人会说。也许表面没有完全按照指定的宽度和高度创建,或者其他(即使输出尺寸是专门为 MediaCodec.class 目标提取的)。

因此,我创建了一个 OpenGL 上下文,为其生成了一个纹理和一个 SurfaceTexture,将其默认缓冲区大小设置为相机输出大小,并使用该纹理创建了一个 Surface。我不会详细介绍将其绘制到 TextureView 或返回到 MediaCodec 的 EGL 表面的细节。结果是一样的 - Camera2 捕获请求仅针对某些分辨率输出失真的图像。 深入挖掘:在 updateTexImage 之后立即在 SurfaceTexture 上调用 getTransformMatrix - 正如预期的那样,矩阵始终是单位矩阵。

所以,这里真正的问题是相机没有以提供的目标表面的大小进行捕捉。因此,解决方案是获得相机正在捕获的 actual 大小,其余的是纯 GL 矩阵变换以正确绘制。但是 - 我如何获得它?

注意:使用旧相机 API,具有与目标完全相同的 "preview size" 和 相同 表面(MediaCodec 的或自定义的) - 一切都很好!但我不能使用旧相机 API,因为它已被弃用,而且似乎最大拍摄尺寸为 1080p,而 Camera2 API 超出了这一点,我需要支持 4k 录制.

所以是的,这是三星设备上的一个错误。

通常,当您在输出中请求多个不同的纵横比时会发生这种情况,并且特定于设备的相机代码在正确裁剪和缩放所有这些时会自我绊倒。您可以通过确保所有请求的尺寸具有相同的宽高比来避免它。

分辨率可能实际上是您要求的 - 但它的缩放比例不正确(您可以使用有问题的大小的 ImageReader 对此进行测试,在那里您可以获得一个可以戳的显式缓冲区。)

我们正在向 Android 合规性测试中添加额外的测试,以确保此类过度输出不会继续发生。

我遇到了类似的问题,模型 SM-A7009 具有 api 级别 21,legacy camera2 设备。

预览被拉伸,surfaceTexture.setDefaultBufferSize 不工作,框架将在预览开始时覆盖这些值。

StreamConfigurationMap.getOutputSizes(SurfaceTexture.class) 报告的预览尺寸并非全部受支持。

只支持其中三个。

$ adb shell dumpsys media.camera |grep preview-size
preferred-preview-size-for-video: 1920x1080
preview-size: 1440x1080
preview-size-values: 1920x1080,1440x1080,1280x720,1056x864,960x720,880x720,800x480,720x480,640x480,528x432,352x288,320x240,176x144

系统转储信息列出了很多预览大小,我检查了所有这些后,我发现只支持1440x1080640x480320x240

支持的预览尺寸都有 1.33333 比例。 CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE.

报告的比率相同

所以我认为这是在 API 21.

中使用旧相机 2 api 的某些三星设备中的错误

解决方案是使用已弃用的相机制作这些设备 API。

希望对到达这里的任何人有所帮助。