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

Kotlin实现相机预览捏合缩放遇‘zoomRatio未解析引用’问题

安卓相机预览捏合缩放实现中出现“Unresolved reference: zoomRatio”错误

问题描述

开发安卓应用相机功能,想要实现相机预览的捏合缩放效果,参考代码后仅出现Unresolved reference: zoomRatio错误,已升级所有依赖至最新版本。

相关代码

缩放监听代码

val listener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
        override fun onScale(detector: ScaleGestureDetector): Boolean {
            // Get the current camera zoom ratio
            val currentZoomRatio: Float = cameraInfo.zoomRatio.value ?: 1F

            // Get by how much the scale has changed due to the user's pinch gesture
            val delta = detector.scaleFactor

            // Update the camera's zoom ratio
            cameraControl.setZoomRatio(currentZoomRatio * delta)
            return true
        }
    }

    val scaleGestureDetector = ScaleGestureDetector(requireContext(), listener)
    progressDialog = ProgressDialog(requireContext(), false)
    binding.cameraPreview.post {
        startCamera()
    }
    binding.ivImageCapture.setOnClickListener {
        progressDialog.show()
        takePicture()
    }

    binding.cameraPreview.setOnTouchListener { _, event ->
        scaleGestureDetector.onTouchEvent(event)
        return@setOnTouchListener true
    }

startCamera函数代码

@SuppressLint("UnsafeExperimentalUsageError")
private fun startCamera() {
    // Get screen metrics used to setup camera for full screen resolution
    val metrics = DisplayMetrics().also { binding.cameraPreview.display.getRealMetrics(it) }

    val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)

    val rotation = binding.cameraPreview.display.rotation


    // Bind the CameraProvider to the LifeCycleOwner
    val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
    val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
    cameraProviderFuture.addListener({

        // CameraProvider
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Preview
        val preview = Preview.Builder()
            .setTargetAspectRatio(screenAspectRatio)
            // Set initial target rotation
            .setTargetRotation(rotation)

            .build()

        preview.setSurfaceProvider(binding.cameraPreview.surfaceProvider)

        // ImageCapture
        imageCapture = initializeImageCapture(screenAspectRatio, rotation)

        // ImageAnalysis


        cameraProvider.unbindAll()

        try { val camera = cameraProvider.bindToLifecycle(
            this, cameraSelector, preview, imageCapture
        )
            cameraControl = camera.cameraControl
            cameraInfo = camera.cameraInfo
            cameraControl.setLinearZoom(0.5f)



        } catch (exc: Exception) {
            exc.printStackTrace()
        }
    }, ContextCompat.getMainExecutor(requireContext()))

解决方案

Unresolved reference: zoomRatio错误的核心原因是CameraX的CameraInfo类没有直接暴露zoomRatio属性,你误用了API名称。以下是修复步骤:

  1. 替换错误的属性调用
    CameraX中需通过CameraInfo.getZoomState()获取ZoomState对象,从中读取当前缩放比例。修改缩放监听的onScale方法:

    override fun onScale(detector: ScaleGestureDetector): Boolean {
        // 获取当前缩放状态,若未初始化则直接返回
        val zoomState = cameraInfo.zoomState.value ?: return false
        // 当前缩放比例
        val currentZoomRatio = zoomState.zoomRatio
        // 计算新缩放比例,并限制在相机硬件支持的范围内
        val newZoomRatio = currentZoomRatio * detector.scaleFactor
        val clampedZoomRatio = newZoomRatio.coerceIn(zoomState.minZoomRatio, zoomState.maxZoomRatio)
        
        // 设置最终缩放比例
        cameraControl.setZoomRatio(clampedZoomRatio)
        return true
    }
    
  2. 确认相机对象初始化时机
    你的startCamera函数中已正确绑定cameraControl和cameraInfo,但需确保这两个对象在调用缩放逻辑前已完成初始化(即相机成功绑定到生命周期后)。

  3. 强制限制缩放范围
    相机硬件对缩放比例有上下限,必须将计算后的缩放值限制在minZoomRatio和maxZoomRatio之间,避免触发异常,上述代码已包含该处理。

内容的提问来源于stack exchange,提问作者Khumo Mashapa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:46:30