14

I am trying to do manual focus on CameraX the same as I do in Camera2 API

in Camera2 API I use the following code

final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 

captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); 

captureBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, mLensFocusDistance);

Can manual focus be done in android camera X? If so how

Thanks in advance

Prashant Sable
  • 1,003
  • 7
  • 19
moLand
  • 143
  • 1
  • 6
  • 1
    Did you figure out how to achieve this in CameraX? – Ehsan Khaveh Feb 10 '20 at 15:05
  • 2
    no camera X is currently unable to https://groups.google.com/a/android.com/forum/#!searchin/camerax-developers/focus%7Csort:date/camerax-developers/ySfolLe_AS8/hOhHRViaCgAJ – moLand Mar 06 '20 at 10:23

2 Answers2

11

There is a way to use manual focus in cameraX by accessing low-level camera2 API with Camera2Interop.Extender. You should set two extra options to preview builder like this:

void setFocusDistance(ExtendableBuilder<?> builder, float distance) {
    Camera2Interop.Extender extender = new Camera2Interop.Extender(builder);
    extender.setCaptureRequestOption(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_OFF);
    extender.setCaptureRequestOption(CaptureRequest.LENS_FOCUS_DISTANCE, distance);
}

And use it when building your cameraX preview request:

float focusDistance = 0F; // example: infinite focus
Preview.Builder previewBuilder = new Preview.Builder();
setFocusDistance(previewBuilder, focusDistance);
preview = previewBuilder.build();
preview.setSurfaceProvider(viewFinder.getSurfaceProvider());

Note that you may also set other camera2 CaptureRequest options in this manner.


Here's how to find the LENS_INFO_MINIMUM_FOCUS_DISTANCE (often a value around 10f):

theCamera = cameraProvider.bindToLifecycle(...
CameraCharacteristics camChars = Camera2CameraInfo
   .extractCameraCharacteristics(theCamera.getCameraInfo());
float discoveredMinFocusDistance = camChars
   .get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
Log.i("dev", "found it! " + discoveredMinFocusDistance);
Fattie
  • 27,874
  • 70
  • 431
  • 719
Mikhail
  • 844
  • 8
  • 18
0

You should set TouchListener to textureView and then set focus(Kotlin):

private fun setUpTapToFocus() {
    textureView.setOnTouchListener { _, event ->
        if (event.action != MotionEvent.ACTION_UP) {
            return false
        }

        val cameraControl = CameraX.getCameraControl(CameraX.LensFacing.BACK) // you can set it to front                     
        val factory = TextureViewMeteringPointFactory(textureView)
        val point = factory.createPoint(event.x, event.y)
        val action = FocusMeteringAction.Builder.from(point).build()
        cameraControl.startFocusAndMetering(action)
        return true
    }
}

Hope that helps

Misha Akopov
  • 12,241
  • 27
  • 68
  • 82