Implement Tap to Focus in Camera2 API

后端 未结 3 1295
故里飘歌
故里飘歌 2020-12-28 20:15

i want to implement tap to focus feature in my custom camera. This is the basic code provided by Google https://github.com/googlesamples/android-Camera2Basic

Here\'s

相关标签:
3条回答
  • 2020-12-28 20:44
    1. Use the onTouch listener to get the point where the user touch the screen.
    2. Calculate a/some MeteringRectangle(s) based on that position.
    3. Use this metering rectangles to set the CaptureRequest.CONTROL_AF_REGION & CaptureRequest.CONTROL_AE_REGION

    4. set the CaptureRequest.CONTROL_AF_MODE to CaptureRequest.CONTROL_AF_MODE_AUTO

    5. CaptureRequest.CONTROL_AF_TRIGGER to CameraMetadata.CONTROL_AF_TRIGGER_START
    6. CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER to CameraMetadata.CONTROL_AE_TRIGGER_START

    7. Then build capture request


    Here you can find a full example.


    0 讨论(0)
  • 2020-12-28 20:46
     public void handleFocus(MotionEvent event) {
        int pointerId = event.getPointerId(0);
        int pointerIndex = event.findPointerIndex(pointerId);
        // Get the pointer's current position
        float x = event.getX(pointerIndex);
        float y = event.getY(pointerIndex);
    
        Rect touchRect = new Rect(
                (int) (x - 100),
                (int) (y - 100),
                (int) (x + 100),
                (int) (y + 100) );
    
    
        if (mCameraId == null) return;
        CameraManager cm = (CameraManager)this.getSystemService(Context.CAMERA_SERVICE);
        CameraCharacteristics cc = null;
        try {
            cc = cm.getCameraCharacteristics(mCameraId);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    
    
        MeteringRectangle focusArea = new MeteringRectangle(touchRect,MeteringRectangle.METERING_WEIGHT_DONT_CARE);
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
        try {
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
            // After this, the camera will go back to the normal state of preview.
            mState = STATE_PREVIEW;
        } catch (CameraAccessException e){
            // log
        }
    
        /* if (isMeteringAreaAESupported(cc)) {
         *//*mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS,
                    new MeteringRectangle[]{focusArea});*//*
        }
        if (isMeteringAreaAFSupported(cc)) {
            *//*mPreviewRequestBuilder
                    .set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_AUTO);*//*
        }*/
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS,
                new MeteringRectangle[]{focusArea});
        mPreviewRequestBuilder
                .set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                CameraMetadata.CONTROL_AF_TRIGGER_START);
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);
        try {
            mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
            /* mManualFocusEngaged = true;*/
        } catch (CameraAccessException e) {
            // error handling
        }
    }
    

    call on touch event method in averide on touch

    0 讨论(0)
  • 2020-12-28 21:05

    You'll need to set the autofocus and auto-exposure region to the area tapped by the user.

    The keys are CONTROL_AF_REGIONS and CONTROL_AE_REGIONS.

    The units for them are in the sensor active array coordinate system, so you'll have to translate from your UI touch coordinates to coordinates relative to your preview view, and from there, to the active array coordinates.

    If the aspect ratio of your preview matches that of the sensor, then that's straightforward; if not, you'll have to adjust for the crop that is done to create the preview output. The best diagram for how the cropping works is currently here. Note that if you're also applying zoom, you'll want to include the zoom factor as well in your calculations.

    Once you've calculated the region, you'll probably want to set the AF mode to AUTO (instead of CONTINUOUS_PICTURE which is usually used for normal preview), and then trigger AF. Once you converge AF (look at the AF state in the capture results, wait for AF_STATE_FOCUSED_LOCKED), you're good to take a picture that's in focus. If you want to return to normal operation after some time or the user cancels the touch to focus, switch AF mode back to CONTINUOUS_PICTURE.

    0 讨论(0)
提交回复
热议问题