【发布时间】:2021-08-16 03:20:16
【问题描述】:
我尝试编写自己的代码来通过 Android 上的 camera2 API 访问相机,而不是使用 Google's example。一方面,我浪费了太多时间来了解到底发生了什么,但另一方面,我注意到了一些非常奇怪的事情:
我希望相机产生垂直图像。然而,尽管ImageReader 的初始化高度大于宽度,但我在onCaptureCompleted 中得到的图像大小相同,只是它旋转了90 度。我一直在努力理解我的错误,所以我去探索谷歌的代码。我发现他们的图像也旋转了 90 度!他们通过在CaptureRequestBuilder 中设置JPEG_ORIENTATION 键来弥补这一点(如果您评论该单行,则保存的图像将被旋转)。这与设备方向无关 - 在我的情况下,应用程序完全禁用了屏幕旋转。
问题在于,出于我正在制作的应用程序的目的,我需要来自相机的非压缩精确数据,因此由于 JPEG a) 压缩图像 b) 有损失,我无法使用它。相反,我使用 YUV_420_888 格式,后来我将其转换为 Bitmap。但是,虽然JPEG_ORIENTATION 标志可以修复 JPEG 图像的方向,但它似乎对 YUV 图像没有任何作用。那么如何让图像正确旋转呢?
一个明显的解决方案是旋转生成的Bitmap,但我不确定我应该在不同的设备上旋转什么角度。更重要的是,是什么导致了这种奇怪的行为?
更新:旋转位图并将其缩放到适当的大小需要太多时间进行预览(上下文如下:我需要处理来自相机的高分辨率图像和缩小的预览中这些相同图像的版本。假设我正在制作类似于 QR 码识别的东西)。我什至尝试过使用 RenderScripts 来有效地操作图像,但这仍然太长了。另外,我读过here,当我同时设置多个输出表面时,所有输出表面都将使用相同的分辨率,这对我来说非常糟糕。
【问题讨论】:
-
请注意,
JPEG_ORIENTATION=90在大多数设备上会生成横向图像(带有 Exif 提示),但在某些设备上可能会生成真正的纵向图像。 -
通常,Jpeg 有损压缩不是问题,因为 Jpeg 中可用的分辨率远高于 YUV 所能达到的分辨率。因此,即使使用有损压缩,您也可以在 Jpeg 中获得更多细节。但这也取决于设备。
-
您可以尝试libyuv在应用旋转的同时将YUV转换为RGB。