From 29ccf4fa6a4db76752e9df8717efddf1e6ea6e97 Mon Sep 17 00:00:00 2001 From: Caleb Lewis Date: Wed, 8 Mar 2017 19:50:53 -0500 Subject: [PATCH] rough draft of implementing autofocus --- .../api16/com/flurgle/camerakit/Camera1.java | 117 +++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java index 0c137ef3..0172ca0a 100644 --- a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java +++ b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java @@ -1,19 +1,25 @@ package com.flurgle.camerakit; +import android.graphics.Rect; import android.graphics.YuvImage; import android.hardware.Camera; import android.media.CamcorderProfile; import android.media.MediaRecorder; +import android.util.Log; +import android.view.MotionEvent; import android.view.SurfaceHolder; +import android.view.View; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.TreeSet; +import static android.content.ContentValues.TAG; import static com.flurgle.camerakit.CameraKit.Constants.FLASH_OFF; import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_CONTINUOUS; import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_OFF; @@ -24,6 +30,11 @@ import static com.flurgle.camerakit.CameraKit.Constants.METHOD_STILL; @SuppressWarnings("deprecation") public class Camera1 extends CameraImpl { + + private static final int FOCUS_AREA_SIZE_DEFAULT = 300; + private static final int FOCUS_METERING_AREA_WEIGHT_DEFAULT = 800; + + private View view; private int mCameraId; private Camera mCamera; private Camera.Parameters mCameraParameters; @@ -32,8 +43,11 @@ public class Camera1 extends CameraImpl { private Size mCaptureSize; private MediaRecorder mMediaRecorder; private File mVideoFile; + private Camera.AutoFocusCallback mAutofocusCallback; private int mDisplayOrientation; + private int mFocusAreaSize = 0; + private int mFocusMeteringAreaWeight = 0; @Facing private int mFacing; @@ -52,6 +66,7 @@ public class Camera1 extends CameraImpl { Camera1(CameraListener callback, PreviewImpl preview) { super(callback, preview); + this.view = preview.getView(); preview.setCallback(new PreviewImpl.Callback() { @Override public void onSurfaceChanged() { @@ -147,7 +162,8 @@ public class Camera1 extends CameraImpl { break; case FOCUS_TAP: - setFocus(FOCUS_CONTINUOUS); + mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + attachFocusTapListener(); break; case FOCUS_OFF: @@ -279,8 +295,107 @@ public class Camera1 extends CameraImpl { return mCamera != null; } + void setFocusAreaSize(int size) { + mFocusAreaSize = size; + } + + /** + * @link {@link android.hardware.Camera.Area#weight} + */ + void setFocusMeteringAreaWeight(int weight) { + mFocusMeteringAreaWeight = weight; + } + + void setTapToAutofocusListener(Camera.AutoFocusCallback callback) { + if (this.mFocus != FOCUS_TAP) { + throw new IllegalArgumentException("Please set the camera to FOCUS_TAP."); + } + + this.mAutofocusCallback = callback; + } + + private int getFocusAreaSize() { + if (mFocusAreaSize == 0) { + return FOCUS_AREA_SIZE_DEFAULT; + } else { + return mFocusAreaSize; + } + } + + private int getFocusMeteringAreaWeight() { + if (mFocusMeteringAreaWeight == 0) { + return FOCUS_METERING_AREA_WEIGHT_DEFAULT; + } else { + return mFocusMeteringAreaWeight; + } + } + // Internal: + private void attachFocusTapListener() { + view.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (mCamera != null ) { + + Camera.Parameters parameters = mCamera.getParameters(); + if (parameters.getMaxNumMeteringAreas() > 0){ + Log.i(TAG,"fancy !"); + Rect rect = calculateFocusArea(event.getX(), event.getY()); + + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + List meteringAreas = new ArrayList<>(); + meteringAreas.add(new Camera.Area(rect, FOCUS_METERING_AREA_WEIGHT_DEFAULT)); + parameters.setFocusAreas(meteringAreas); + + mCamera.setParameters(parameters); + mCamera.autoFocus(new Camera.AutoFocusCallback() { + @Override + public void onAutoFocus(boolean success, Camera camera) { + if (mAutofocusCallback != null) { + mAutofocusCallback.onAutoFocus(success, camera); + } + } + }); + } else { + mCamera.autoFocus(new Camera.AutoFocusCallback() { + @Override + public void onAutoFocus(boolean success, Camera camera) { + if (mAutofocusCallback != null) { + mAutofocusCallback.onAutoFocus(success, camera); + } + } + }); + } + } + } + return true; + } + }); + } + + private Rect calculateFocusArea(float x, float y) { + int left = clamp(Float.valueOf((x / view.getWidth()) * 2000 - 1000).intValue(), getFocusAreaSize()); + int top = clamp(Float.valueOf((y / view.getHeight()) * 2000 - 1000).intValue(), getFocusAreaSize()); + + return new Rect(left, top, left + getFocusAreaSize(), top + getFocusAreaSize()); + } + + private int clamp(int touchCoordinateInCameraReper, int focusAreaSize) { + int result; + if (Math.abs(touchCoordinateInCameraReper)+focusAreaSize/2>1000){ + if (touchCoordinateInCameraReper>0){ + result = 1000 - focusAreaSize/2; + } else { + result = -1000 + focusAreaSize/2; + } + } else{ + result = touchCoordinateInCameraReper - focusAreaSize/2; + } + return result; + } + private void openCamera() { if (mCamera != null) { releaseCamera();