Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to implement Touch-to-Focus in Android using Camera2 APIs
//Override in your touch-enabled view (this can be differen than the view you use for displaying the cam preview)
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
final int actionMasked = motionEvent.getActionMasked();
if (actionMasked != MotionEvent.ACTION_DOWN) {
return false;
}
if (mManualFocusEngaged) {
Log.d(TAG, "Manual focus already engaged");
return true;
}
final Rect sensorArraySize = mCameraInfo.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
//TODO: here I just flip x,y, but this needs to correspond with the sensor orientation (via SENSOR_ORIENTATION)
final int y = (int)((motionEvent.getX() / (float)view.getWidth()) * (float)sensorArraySize.height());
final int x = (int)((motionEvent.getY() / (float)view.getHeight()) * (float)sensorArraySize.width());
final int halfTouchWidth = 150; //(int)motionEvent.getTouchMajor(); //TODO: this doesn't represent actual touch size in pixel. Values range in [3, 10]...
final int halfTouchHeight = 150; //(int)motionEvent.getTouchMinor();
MeteringRectangle focusAreaTouch = new MeteringRectangle(Math.max(x - halfTouchWidth, 0),
Math.max(y - halfTouchHeight, 0),
halfTouchWidth * 2,
halfTouchHeight * 2,
MeteringRectangle.METERING_WEIGHT_MAX - 1);
CameraCaptureSession.CaptureCallback captureCallbackHandler = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
mManualFocusEngaged = false;
if (request.getTag() == "FOCUS_TAG") {
//the focus trigger is complete -
//resume repeating (preview surface will get frames), clear AF trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null);
mCameraOps.setRepeatingRequest(mPreviewRequestBuilder.build(), null, null);
}
}
@Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
Log.e(TAG, "Manual AF failure: " + failure);
mManualFocusEngaged = false;
}
};
//first stop the existing repeating request
mCameraOps.stopRepeating();
//cancel any existing AF trigger (repeated touches, etc.)
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
mCameraOps.capture(mPreviewRequestBuilder.build(), captureCallbackHandler, mBackgroundHandler);
//Now add a new AF trigger with focus region
if (isMeteringAreaAFSupported()) {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusAreaTouch});
}
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
mPreviewRequestBuilder.setTag("FOCUS_TAG"); //we'll capture this later for resuming the preview
//then we ask for a single request (not repeating!)
mCameraOps.capture(mPreviewRequestBuilder.build(), captureCallbackHandler, mBackgroundHandler);
mManualFocusEngaged = true;
return true;
}
private boolean isMeteringAreaAFSupported() {
return mCameraInfo.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF) >= 1;
}
@meetharia

This comment has been minimized.

Copy link

@meetharia meetharia commented Apr 16, 2017

Can you please provide full code access link to hariameet27@gmail.com . It would be very helpful

@CodeByNitin

This comment has been minimized.

Copy link

@CodeByNitin CodeByNitin commented Apr 21, 2017

Can you please provide full code. it would be very helpfull.

@Ashky

This comment has been minimized.

Copy link

@Ashky Ashky commented Apr 21, 2017

Ty man :D works perfect

@SmLiar

This comment has been minimized.

Copy link

@SmLiar SmLiar commented May 26, 2017

Really thank you so much! Your code is very helpful to me!

@ColinWang1203

This comment has been minimized.

Copy link

@ColinWang1203 ColinWang1203 commented Jul 28, 2017

I Love You

@siralam

This comment has been minimized.

Copy link

@siralam siralam commented Dec 8, 2017

Sad... I copied everything, but when I tap on the view, the Texture view freezes. I added breakpoint, and can reach onCaptureCompleted with the correct tag ("FOCUS_TAG"). The line mCameraOps.setRepeatingRequest(mPreviewRequestBuilder.build(), null, null); should be executed without problem, but the preview still freezes.

@Nan0fm

This comment has been minimized.

Copy link

@Nan0fm Nan0fm commented Dec 20, 2017

@siralam I have same problem...((
maybe, you are already solved it?

@ZhengShang

This comment has been minimized.

Copy link

@ZhengShang ZhengShang commented Dec 25, 2017

In some devices(Sony xperia G8142 etc..),CaptureRequest.CONTROL_AF_TRIGGER can not be set to null,or the camera throws an error. but how to solve this, I have no idea..

@krishnanrao

This comment has been minimized.

Copy link

@krishnanrao krishnanrao commented Jan 10, 2018

can you please give me access to the code my email id : krishna.bn05@gmail.com

@JeetSingh4

This comment has been minimized.

Copy link

@JeetSingh4 JeetSingh4 commented Feb 10, 2018

It only works well with flash OFF, app freezes when you try to capture with flash ON and touch on surface. :(

@hrieke

This comment has been minimized.

Copy link

@hrieke hrieke commented Jan 20, 2019

License?

@gigadeplex

This comment has been minimized.

Copy link

@gigadeplex gigadeplex commented Jan 23, 2019

Hey guys @Nan0fm @siralam (possibly @JeetSingh4 as well), simple fix, don't know if it's the correct fix but it works (and without freezing anything), remove captureCallbackHandler from the captures and where it says "//then we ask for a single request (not repeating!)" change it from .capture to .setRepeatingRequest. Finally you will run into the boolean lock caused by "mManualFocusEngaged" so set line 79: "mManualFocusEngaged = true;" to "mManualFocusEngaged = false;" and add "mManualFocusEngaged=true" in line 23

@sirius94

This comment has been minimized.

Copy link

@sirius94 sirius94 commented Apr 3, 2019

In some devices(Sony xperia G8142 etc..),CaptureRequest.CONTROL_AF_TRIGGER can not be set to null,or the camera throws an error. but how to solve this, I have no idea..

I found that setting CONTROL_AF_TRIGGER to CONTROL_AF_TRIGGER_IDLE instead of null works on Xperia devices.

@ansman

This comment has been minimized.

Copy link

@ansman ansman commented May 10, 2019

This code does not take in to account rotation or cropping. If you are displaying a video feed in 1920x1080 tapping in 0,0 should probably not focus in 0, 0 in sensor coordinates.

@VinnyKinger

This comment has been minimized.

Copy link

@VinnyKinger VinnyKinger commented Jun 13, 2019

can you please provide me full code at my email id : kingervinny@gmail.com . Thanks in advance.

@woobeanpapa

This comment has been minimized.

Copy link

@woobeanpapa woobeanpapa commented Jun 18, 2019

can you please provide me full code at my email id : kjcsp321@gmail.com . Thanks in advance.

@techashu

This comment has been minimized.

Copy link

@techashu techashu commented Jul 16, 2019

Can you please provide full code access link to victorvishal23@gmail.com . It would be very helpful

@jyotirmayghosh

This comment has been minimized.

Copy link

@jyotirmayghosh jyotirmayghosh commented Sep 6, 2019

Sad... I copied everything, but when I tap on the view, the Texture view freezes. I added breakpoint, and can reach onCaptureCompleted with the correct tag ("FOCUS_TAG"). The line mCameraOps.setRepeatingRequest(mPreviewRequestBuilder.build(), null, null); should be executed without problem, but the preview still freezes.

Hey, if you have the executing code can you please share the link to jyotirmay.ghosh2@gmail.com

@mortenholmgaard

This comment has been minimized.

Copy link

@mortenholmgaard mortenholmgaard commented Nov 27, 2019

Does any one have the full code? And has any one else implemented it base on this? How do you handle the default initialization of thoes variables?

@rtsdemo123

This comment has been minimized.

Copy link

@rtsdemo123 rtsdemo123 commented Dec 12, 2019

@mortenholmgaard
I took used the google sample project that is using camera api 2 from here
https://github.com/android/camera-samples/tree/master/Camera2BasicJava/Application/src/main/java/com/example/android/camera2basic
After you manage to work with this example just copy and paste the onTouch code and it will work.

There is still an issue which I'm trying currently to figure out, after you do an auto focus you are not able to capture a photo.
I will update if I will manage to fix it, feel free to ask questions, if you got to some problems.

@logapriyasundaram

This comment has been minimized.

Copy link

@logapriyasundaram logapriyasundaram commented Sep 19, 2020

can you please provide me full code at my email id :logapriyasa@gmail.com . Thanks in advance.

@saurabhathavale

This comment has been minimized.

Copy link

@saurabhathavale saurabhathavale commented Oct 5, 2020

can you please provide me full code at my email - saurabhathavale02@gmail.com.Thanks in advance

@MeOnGithub964

This comment has been minimized.

Copy link

@MeOnGithub964 MeOnGithub964 commented Mar 7, 2021

How to touch on focus using CameraX library and how to disable autofocus? Only focus on touch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment