Search code examples
androidkotlinzoomingandroid-camerax

Why can't CameraX zoom in a picture as larger as I need in Android Studio?


I'm learning CameraX, and CameraXBasic is a sample code.

I write a zoomX function based CameraFragment.kt. you can see the Code A. I think the function can zoom in a picture any time.

I find that a picture can be zoom in when I invoke it with s a small value, such as zoomX(2f), zoomX(3f), but the picture will not be zoom in again when I use a big value such as zoomX(6.0f), zoomX(7.0f)... why?

Code A

   private lateinit var viewFinder: TextureView 
    private var preview: Preview? = null

    fun zoomX(orign: Float ){       
        val x=orign+1

        val singleWidth=viewFinder.width/x
        val singleHeight=viewFinder.height/x

        val left=viewFinder.width/2f-singleWidth/2f
        val right=left+singleWidth
        val top=viewFinder.height/2f-singleHeight/2f
        val bottom=top+singleHeight

        val my= Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
        preview?.zoom(my)      
    }

Solution

  • This is not a matter of tradition, but of Futures. Updating that CameraXBasic example from 1.0.0-alpha06 to 1.0.0-alpha08 breaks a lot, but CameraX CameraControl features these two methods:

    Sets current zoom by a linear zoom value ranging from 0f to 1.0f.

    linearZoom 0f represents the minimum zoom while linearZoom 1.0f represents the maximum zoom. The advantage of linearZoom is that it ensures the field of view (FOV) varies linearly with the linearZoom value, for use with slider UI elements (while setZoomRatio(float) works well for pinch-zoom gestures).

    Sets current zoom by ratio.

    It modifies both current zoomRatio and linearZoom so if apps are observing zoomRatio or linearZoom, they will get the update as well. If the ratio is smaller than CameraInfo.getMinZoomRatio() or larger than CameraInfo.getMaxZoomRatio(), the returned ListenableFuture will fail with IllegalArgumentException and it won't modify current zoom ratio. It is the applications' duty to clamp the ratio.

    Also see Executor and there's also CameraXExecutors.


    Also see the release notes or the commits ...for all the API changes, which break the CameraXBasic example. I won't explain any more of these API differences (since this wasn't the question), but have forked it; see issues #131 (so far, at least the preview works there).


    This is how it actually works:

    val camera: Camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview)
    val control: CameraControl = camera.cameraControl
    control.setZoomRatio(5.0f)
    

    Zoom ratios from 1.0f until 8.0f work on my Motorola XT1900:

    val info: CameraInfo = camera.cameraInfo
    val cameraId = (info as Camera2CameraInfoImpl).cameraId
    val zoomRatio = info.getZoomRatio().value
    val maxZoomRatio = info.getMaxZoomRatio().value
    val minZoomRatio = info.getMinZoomRatio().value
    val linearZoom = info.getLinearZoom().value