Search code examples
javaandroidkotlincameraandroid-camerax

How to ensure focused before taking picture in Android CameraX? (Should be a very commonly used feature!)


I am using CameraX and want to take a photo. Of course, no one wants a blurred picture, so we should ensure focused before taking picture.

First attempt: Simply call takePicture like what is done in the official sample.

Problem: I can change the scene and quickly press the take photo button. Then, the camera has not finished auto focus when the takePicture happens. Therefore, I get a blurred photo :/

Second attempt: Before actually taking photo, firstly trigger focusing and wait for it to finish.

Code like:

camera!!.cameraControl.startFocusAndMetering(
                    FocusMeteringAction.Builder(
                            autoFocusPoint,
                            FocusMeteringAction.FLAG_AF
                    ).apply {
                        //focus only when the user tap the preview
                        disableAutoCancel()
                    }.build()
            )

Problem: It takes so long to do a focus (seconds!). Users definitely cannot accept that.

Therefore, I wonder what should I do? IMHO this should be very commonly used, so I am surprised to see that I cannot find any solution! Do I miss something?

Thanks for any suggestions!


Solution

  • I found the answer! Simply call setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY).

    Reason: look at ImageCapture's constructor:

            if (mCaptureMode == CAPTURE_MODE_MAXIMIZE_QUALITY) {
                mEnableCheck3AConverged = true; // check 3A convergence in MAX_QUALITY mode
            } else {
                mEnableCheck3AConverged = false; // skip 3A convergence in MIN_LATENCY mode
            }
    

    And that field:

        /**
         * A flag to check 3A converged or not.
         *
         * <p>In order to speed up the taking picture process, trigger AF / AE should be skipped when
         * the flag is disabled. Set it to be enabled in the maximum quality mode and disabled in the
         * minimum latency mode.
         */
        private final boolean mEnableCheck3AConverged;
    

    Aha!