如何使用CameraX设置正确的宽高比?

9
我正在按照CameraX codelab 的指导进行操作,但是即使使用了 setTargetAspectRatiosetTargetResolution 方法,在预览中仍然得到错误的宽高比。
private fun startCamera() {
    // Create configuration object for the viewfinder use case
    val previewConfig = PreviewConfig.Builder().apply {
        setTargetAspectRatio(Rational(1, 1))
        setTargetResolution(Size(640, 640))
    }.build()
    ...

布局使用编码硬编码的大小,如在代码实验中所示。

<TextureView
    android:id="@+id/view_finder"
    android:layout_width="640px"
    android:layout_height="640px"
    ...

希望库中有CameraTextureView和一个属性android:scaleType(类似于现有的用于ImageView的属性),以便调整预览大小适应预览尺寸。

CameraX wrong aspect ratio

4个回答

21

你试过吗?

    val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
    val screenSize = Size(metrics.widthPixels, metrics.heightPixels)
    val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)

    val viewFinderConfig = PreviewConfig.Builder().apply {
            //...
            setTargetResolution(screenSize)
            setTargetAspectRatio(screenAspectRatio)
            setTargetRotation(viewFinder.display.rotation)
        }.build()

    val preview = AutoFitPreviewBuilder.build(viewFinderConfig, viewFinder)

你可以在这里找到AutoFitPreviewBuilder: https://gist.github.com/yevhenRoman/90681822adef43350844464be95d23f1

建议你使用dp或约束来设置TextureView的宽度和高度。 如果对你有用,请让我知道,谢谢!


5
抱歉,还是没起作用 :( 预览图片仍然被拉伸了... 关于视图大小,我知道使用 dp 是推荐的方法,但我只是按照 codelab 的指导操作。 - nglauber
1
奇怪的事情。这是alpha版本,可能现在无法在某些设备上运行。 希望您能解决这个问题,祝好运! - yevhen_69
2
@nglauber,你尝试使用示例代码了吗?如果你克隆并按原样运行此代码会发生什么:https://github.com/android/camera/tree/master/CameraXBasic - Oscar Wahltinez
4
@OscarWahltinez,示例代码运行良好。经过比较,我注意到当我移除这个调用 preview.setOnPreviewOutputUpdateListener 时,预览不再被拉伸。感谢你的提示。 然而,整个预览(一个矩形)位于视图(一个矩形)内部,类似于 ImageView 的 CENTER_INSIDE 缩放类型,我想要类似于 CENTER_CROP 的效果。这引出了我问题的第二点:希望能够有一个 CameraTextureView,可以设置相机预览的缩放类型。 - nglauber
2
setTargetAspectRatio需要一个AspectRatio类型的int,不再支持有理数了:( - ch271828n
显示剩余4条评论

2

这个问题是关于CameraX而不是Camera2的。此外,它对我没有起作用。 - Jashanpreet singh Chakkal

2
根据官方Android文档“不允许在同一用例中设置目标宽高比和目标分辨率。”虽然编译器不会报错,但可能会导致意外结果。

请注意,此答案中的链接现在返回 404 错误,但是关于 CameraX 的文档现在建议您可以同时设置纵横比和分辨率:「默认情况下,目标分辨率设置为 640x480,所以如果您想要比 640x480 更大的分辨率,您必须使用 setTargetResolution() 和 setTargetAspectRatio() 方法从支持的分辨率中选择最接近的一个。」https://developer.android.com/training/camerax/configuration。然而,对我来说并没有起作用,它抛出了一个致命异常。 - undefined

0

您可以使用Matrix来设置TextureView的宽高比,如下所示:

Matrix txform = new Matrix();
textureView.getTransform(txform);
txform.setScale((float) = videoWidth / viewWidth, (float) videoHeight / viewHeight);// aspect ratio
textureView.setTransform(txform); // apply matrix

你看了我提到的代码实验室吗?好吧,如果你看一下第6步,updateTransform会更新TextureView。我尝试了你的建议,在这个方法中使用了matrix.setScale(960f / 640, 720f / 640)(960x720是有效的相机分辨率,而纹理大小为640x640),但并没有起作用,预览仍然被拉伸了。 - nglauber
我认为拉伸的预览图像可能是由Preview.PreviewOutput返回的FixedSizeSurfaceTexture引起的。它的长宽比与其所附加的预览不同。因此,我尝试按照您已经提到的方式进行缩放:matrix.setScale((float) = videoWidth / viewWidth, (float) videoHeight / viewHeight),但这并没有解决拉伸效果。 - jns

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