Nexus 7相机预览大小:无法改变宽高比。

3

我在我的Android应用程序中使用SurfaceView显示实时摄像头预览图像。 SurfaceView覆盖了竖屏屏幕的整个宽度和一部分高度。

我尝试设置各种预览大小,因此预览具有扭曲的宽高比,矮胖或高瘦。

我打印了调试信息,显示实际预览显示大小和可用的预览相机大小,以便我可以计算出宽高比误差。

Screen size available for preview: w*h:1200*1646; Aspect ratio: 0.73
Rotation: 0; finalCameraRotation: 90; sideways: true
Supported Preview size: w*h:1080*1920: AspectRatio: 0.56: Error: -22.84%
Supported Preview size: w*h:768*1280: AspectRatio: 0.60: Error: -17.70%
...

通常情况下,我会选择纵横比误差最小的预览尺寸,但这次我在进行实验。
List<Camera.Size> ss = parameters.getSupportedPreviewSizes();
...
Camera.Size s = ss.get(pickOne);
parameters.setPreviewSize(s.width, s.height);
...
camera.setParameters(parameters);
...
camera.startPreview();

我通过将相机对准白色正方形并使用Eclipse截屏,然后使用Photoshop的标尺工具测量截屏中白色正方形的图像来测量预览显示的长宽比误差:screenshot of Photoshop measuring square
我测量了正方形在屏幕像素上的xy大小,并计算出1-(y/x),这应该与上面调试日志中预测的长宽比误差相同。
我在以下设备上进行了测试:
  • Alcatel 995, Android 4.0.4
  • Samsung Note 2, Android 4.4.2
  • Google Nexus 7, Android 4.4.4
  • Google Nexus 5, Android 5.0
在这些设备上,我测量了各种长宽比,最大误差为25%左右,但在所有设备中,我测量到的预览长宽比与预测值相差不到1%。(可能存在误差,例如相机可能没有正对屏幕,可能有点模糊...) 除了Google Nexus 7。 无论我为Nexus 7设置什么预览大小,测量得到的长宽比都偏高约2%,这恰好是可用的最佳长宽比。
Supported Preview size: w*h:768*1024: AspectRatio: 0.75: Error: 2.87%

好像有其他程序在我设置最佳预览大小后进行修复。我实际上编写了代码等待10秒钟并从相机中读取预览大小,而它正是我设置的大小,但显示并没有反映出来。无论我设置什么预览大小,显示总是最佳的。

Nexus 7的预览大小有什么奇怪的地方吗?

我知道我的setPreviewSize正在做某些事情,因为我可以将预览设置为144 * 176px,然后我会在显示屏上看到奇怪的上采样像素化伪影。但它仍然具有几乎正确的宽高比!

2个回答

1
我刚遇到了这个问题。据报道,当相机的图片大小和预览大小参数具有不同的宽高比时,某些设备会出现此问题。在我的情况下,无论我设置什么,我的 Nexus 7 显示始终使用 4:3 预览。而且,getPreviewSize() 报告的是我设置的尺寸,而不是实际使用的尺寸。
解决方法是找到一个与预览的宽高比匹配的图片大小。因此,使用 getSupportedPictureSizes() 获取支持的图片大小列表,选择一个具有适当宽度/高度比的大小,然后使用 setPictureSize(int width, int height)。它对我非常有效 :)

0

No matter what preview size I set for the Nexus 7, the measured aspect ratio was about 2% too tall, which just happens to be the best possible aspect ratio available:

Supported Preview size: w*h:768*1024: AspectRatio: 0.75: Error: 2.87%

[…] Is there something weird about preview sizes on Nexus 7?

答案:是的,有一些奇怪的问题……

Nexus 7的一个错误是,它所有的预览尺寸都包含4:3的图像数据,被拉伸到预览帧的大小。换句话说: Nexus 7取景器帧的内容始终是通过将1920×1440像素的图像1(4:3)非比例缩放到所选的实时相机预览大小而获得的。这意味着按需要拉伸缩放,而不裁剪任何内容。

现在,这就是你观察到问题描述中所描述行为的原因:偶然情况下,你可用的屏幕空间1646×1200几乎是4:3。因此,将Nexus 7提供的4:3图像数据缩放到该尺寸将始终导致观察到的低长宽比误差(2.87%)。缩放到预览大小的中间步骤不会改变任何内容,因为它会被随后的缩放到可用屏幕大小所撤消。

这是一个错误

你很幸运,你可用的屏幕尺寸是4:3,从而导致了来自Nexus 7的适当预览。然而,其他人将会遇到一个问题,即Nexus 7的预览在其指示的自然尺寸下显示时会出现扭曲。

例如:Nexus 7报告许多可用的预览尺寸,其宽高比不是4:3;让我们以1920×1080(宽高比1.78)为例。在1920×1080矩形中显示4:3帧内容会导致图像拉伸。
因此,Nexus 7的预览行为肯定存在错误。错误似乎在于4:3预览适用于静态图像,而19:10预览适用于视频图像,但是帧错误地始终包含4:3图像数据。或者反过来:相机报告了这两种类型的预览尺寸,而其当前模式仅允许4:3或19:10预览。
解决方法
必须有一种适当的方法来解决这个问题,因为Nexus 7本地相机应用程序在视频模式下提供了一个没有失真的19:10预览(意味着它不包含4:3图像数据)。

正如@fljau在其他答案中所报告的那样,将相机的静态图像捕获分辨率设置为与您选择的预览的宽高比匹配即可解决此问题。然后,您可以以其自然、报告的大小显示相机实时预览,并且屏幕上的圆形对象不会出现扭曲。

我在Qt QML中按照以下方式执行了此操作:

Camera {
    imageCapture {
        resolution: "1920x1080"
    }
    viewfinder.resolution: "1920x1080"
}

设置Camera { captureMode: CaptureStillImage }并不是必要的。静态图像分辨率会影响任何captureMode的预览图像数据,这是一个副作用(使其更清晰地表明这确实是一个错误)。

对于QML中的通用、与模型无关的解决方案,您可以通过可用取景器分辨率,然后通过可用静态图像分辨率,然后将imageCapture.resolution设置为上述值,以匹配纵横比最大(或所需)的取景器分辨率。

替代解决方案

当您知道预览帧内数据的实际纵横比时,您可以显示相机实时预览非比例缩放以匹配此纵横比。基本上,这就是问题作者意外做到的(误差范围为2.87%)。

我也尝试将捕获模式设置为“视频”,希望它会导致19:10的“视频风格”预览帧内容,但并没有起作用。(参考资料,我在Qt QML中尝试了Camera { captureMode: Camera.CaptureVideo }。)那也不行。

1 一个1920×1440像素的图像只是一个4:3的图像,足够大以覆盖最大支持的预览尺寸1920×1080像素。我为了论证而创造了这个尺寸,以便缩放不会丢失在预览中看到的像素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接