You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android CameraX如何设置相机捕获比例并实现全屏显示?

解决CameraX预览无法全屏显示的问题

针对你遇到的CameraX预览无法全屏的问题,核心问题出在PreviewView的缩放类型和分辨率策略的匹配逻辑上,以下是具体的修复步骤:

1. 修改PreviewView的缩放类型

你当前设置的FIT_CENTER会让相机画面按原始比例居中显示,无法填充整个PreviewView,导致出现黑边。需要将其改为填充模式:

previewView.scaleType = PreviewView.ScaleType.FILL_START

FILL_START会让画面填充整个PreviewView(可能会裁剪部分画面),如果需要保持画面居中裁剪,可以改用FILL_CENTER。

2. 让分辨率策略匹配PreviewView的宽高比

固定设置1280×1280的分辨率可能和PreviewView的实际宽高比不匹配,且相机硬件可能不支持该比例,导致CameraX自动回退到其他分辨率。正确的做法是优先匹配PreviewView的比例:

步骤2.1 确保获取到PreviewView的实际宽高

由于View初始化时可能还未完成测量,直接获取宽高会得到0,需要监听View的布局完成事件后再初始化相机:

// 在初始化CameraManager的地方添加监听
previewView.addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
    override fun onLayoutChange(
        v: View?, left: Int, top: Int, right: Int, bottom: Int,
        oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int
    ) {
        if (previewView.width > 0 && previewView.height > 0) {
            startCamera()
            previewView.removeOnLayoutChangeListener(this) // 只执行一次
        }
    }
})

步骤2.2 调整ResolutionSelector的配置

在startCamera()方法中,根据PreviewView的实际宽高比构建分辨率选择器,优先匹配该比例的分辨率:

fun startCamera() {
    previewView.scaleType = PreviewView.ScaleType.FILL_START
    
    // 获取PreviewView的宽高比
    val previewRatio = Rational(previewView.width, previewView.height)
    
    val resolutionSelector = ResolutionSelector.Builder()
        // 优先选择与PreviewView比例匹配的分辨率
        .setAspectRatioStrategy(
            AspectRatioStrategy(
                previewRatio,
                AspectRatioStrategy.FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER
            )
        )
        // 如果需要限制分辨率范围,可以添加以下配置(可选)
        // .setResolutionStrategy(
        //     ResolutionStrategy(
        //         Size(1920, 1080), // 目标分辨率,根据需求调整
        //         ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER
        //     )
        // )
        .build()

    val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
    cameraProviderFuture.addListener({
        val cameraProvider = cameraProviderFuture.get()
        preview = Preview.Builder()
            .setResolutionSelector(resolutionSelector)
            .build()

        // 让ImageAnalysis也使用相同的分辨率选择器,避免多UseCases冲突
        imageAnalysis = ImageAnalysis.Builder()
            .setResolutionSelector(resolutionSelector)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()
            .also {
                it.setAnalyzer(cameraExecutor, qrCodeProcessor)
            }

        val cameraSelector = CameraSelector.Builder()
            .requireLensFacing(cameraSelectorOption)
            .build()

        imageCapture = ImageCapture.Builder()
            .setResolutionSelector(resolutionSelector)
            .build()
        setCameraConfig(cameraProvider, cameraSelector)
    }, ContextCompat.getMainExecutor(context))
}

3. 统一所有UseCases的分辨率策略

确保Preview、ImageAnalysis、ImageCapture三个UseCases使用相同的ResolutionSelector,CameraX会自动选择一个所有UseCases都支持的最优分辨率,避免因分辨率要求不一致导致的显示异常。

额外注意事项

  • 相机硬件支持的分辨率是有限的,如果强制设置一个硬件不支持的比例或分辨率,CameraX会自动回退到最近的支持选项,这可能导致显示不符合预期。
  • 如果需要完全无裁剪的全屏显示,需要确保相机输出的分辨率比例和PreviewView的比例完全一致,否则只能通过裁剪或拉伸来填充(拉伸会导致画面变形,不推荐)。

内容的提问来源于stack exchange,提问作者Louis Berthier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:00:01