androidcameragoogle-play-servicesgoogle-visionandroid-vision

Google Vision API Samples: Get the CameraSource to Focus


I have checkout out the latest Google Vision APIs from here:

https://github.com/googlesamples/android-vision

And I am running it on a LG G2 device with KitKat. The only change I have made is to the minSdkVerion in the Gradle file:

...
defaultConfig {
    applicationId "com.google.android.gms.samples.vision.face.multitracker"
    minSdkVersion 19
...

However it does not focus. How do I make it focus?


Solution

  • I modified the CameraSourcePreview (....) constructor to be as follows:

    public CameraSourcePreview(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mStartRequested = false;
        mSurfaceAvailable = false;
    
        mSurfaceView = new SurfaceView(context);
        mSurfaceView.getHolder().addCallback(new SurfaceCallback());
        addView(mSurfaceView);
        mSurfaceView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                cameraFocus(mCameraSource, Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            }
        });
    }
    
    private static boolean cameraFocus(@NonNull CameraSource cameraSource, @NonNull String focusMode) {
        Field[] declaredFields = CameraSource.class.getDeclaredFields();
    
        for (Field field : declaredFields) {
            if (field.getType() == Camera.class) {
                field.setAccessible(true);
                try {
                    Camera camera = (Camera) field.get(cameraSource);
                    if (camera != null) {
                        Camera.Parameters params = camera.getParameters();
                        params.setFocusMode(focusMode);
                        camera.setParameters(params);
                        return true;
                    }
    
                    return false;
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
    
                break;
            }
        }
    
        return false;
    }
    

    The advice was given here: https://github.com/googlesamples/android-vision/issues/2

    and the code reference was here: https://gist.github.com/Gericop/7de0b9fdd7a444e53b5a

    I also had to modify the FaceTrackerFactory draw(Canvas ...) method:

    @Override
    public void draw(Canvas canvas) {
        Face face = mFace;
        if (face == null) {
            return;
        }
    
        // Draws a circle at the position of the detected face, with the face's track id below.
        float cx = translateX(face.getPosition().x + face.getWidth() / 2);
        float cy = translateY(face.getPosition().y + face.getHeight() / 2);
        canvas.drawCircle(cx, cy, FACE_POSITION_RADIUS, mFacePositionPaint);
        canvas.drawText("id: " + getId(), cx + ID_X_OFFSET, cy + ID_Y_OFFSET, mIdPaint);
    
        // Draws an oval around the face.
        float xOffset = scaleX(face.getWidth() / 2.0f);
        float yOffset = scaleY(face.getHeight() / 2.0f);
        float left = cx - xOffset;
        float top = cy - yOffset;
        float right = cx + xOffset;
        float bottom = cy + yOffset;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            canvas.drawOval(left, top, right, bottom, mBoxPaint);
        } else {
            canvas.drawCircle(cx, cy, Math.max(xOffset, yOffset), mBoxPaint);
        }
    }