Real tap-to-focus support, was heavily bugged

pull/1/head
Mattia Iavarone 7 years ago
parent 5d052d3577
commit 3f67e02d1e
  1. 10
      README.md
  2. 81
      camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java

@ -4,16 +4,16 @@
- lots *of serious bugs fixed, I have lost the count* - lots *of serious bugs fixed, I have lost the count*
- *decent orientation support for both pictures and videos* - *decent orientation support for both pictures and videos*
- *EXIF support* - *EXIF support*
- *simpler APIs* - *real tap-to-focus support*
- *docs and comments in code* - *simpler APIs, docs and heavily commented code*
- *introduced sessionType (picture or video), replacing Method and Permissions stuff* - *replacing Method and Permissions stuff with `sessionType`*
- *new `captureSnapshot` API* - *new `captureSnapshot` API*
- *new `setLocation` and `setWhiteBalance` APIs* - *new `setLocation` and `setWhiteBalance` APIs*
- *new `setGrid` APIs, to draw 3x3, 4x4 or golden ratio grids
- *option to pass a `File` when recording a video* - *option to pass a `File` when recording a video*
- *introduced a smart measuring and sizing behavior, replacing bugged `adjustViewBounds`* - *smart measuring and sizing behavior, replacing bugged `adjustViewBounds`*
- *measure `CameraView` as center crop or center inside* - *measure `CameraView` as center crop or center inside*
- *add multiple `CameraListener`s for events* - *add multiple `CameraListener`s for events*
- *new `setGrid` APIs, to draw 3x3, 4x4 or golden ratio grids
*Feel free to open issues with suggestions or contribute.* *Feel free to open issues with suggestions or contribute.*

@ -31,8 +31,6 @@ class Camera1 extends CameraImpl {
private static final String TAG = Camera1.class.getSimpleName(); private static final String TAG = Camera1.class.getSimpleName();
private static final int FOCUS_AREA_SIZE_DEFAULT = 200;
private static final int FOCUS_METERING_AREA_WEIGHT_DEFAULT = 1000;
private static final int DELAY_MILLIS_BEFORE_RESETTING_FOCUS = 3000; private static final int DELAY_MILLIS_BEFORE_RESETTING_FOCUS = 3000;
private int mCameraId; private int mCameraId;
@ -672,17 +670,16 @@ class Camera1 extends CameraImpl {
if (!mFocusOnTap) return; if (!mFocusOnTap) return;
if (mCamera == null) return; if (mCamera == null) return;
if (event.getAction() != MotionEvent.ACTION_UP) return; if (event.getAction() != MotionEvent.ACTION_UP) return;
Rect rect = calculateFocusArea(event.getX(), event.getY()); List<Camera.Area> meteringAreas2 = computeMeteringAreas(event.getX(), event.getY());
List<Camera.Area> meteringAreas = new ArrayList<>(); List<Camera.Area> meteringAreas1 = meteringAreas2.subList(0, 1);
meteringAreas.add(new Camera.Area(rect, getFocusMeteringAreaWeight()));
synchronized (mLock) { synchronized (mLock) {
Camera.Parameters parameters = mCamera.getParameters(); Camera.Parameters parameters = mCamera.getParameters();
boolean autofocusSupported = parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO); boolean autofocusSupported = parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO);
if (autofocusSupported) { if (autofocusSupported) {
if (parameters.getMaxNumFocusAreas() > 0) parameters.setFocusAreas(meteringAreas); int maxAF = parameters.getMaxNumFocusAreas();
if (parameters.getMaxNumMeteringAreas() > 0) int maxAE = parameters.getMaxNumMeteringAreas();
parameters.setMeteringAreas(meteringAreas); if (maxAF > 0) parameters.setFocusAreas(maxAF > 1 ? meteringAreas2 : meteringAreas1);
if (maxAE > 0) parameters.setMeteringAreas(maxAE > 1 ? meteringAreas2 : meteringAreas1);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCamera.setParameters(parameters); mCamera.setParameters(parameters);
mCamera.autoFocus(new Camera.AutoFocusCallback() { mCamera.autoFocus(new Camera.AutoFocusCallback() {
@ -696,15 +693,6 @@ class Camera1 extends CameraImpl {
} }
private int getFocusAreaSize() {
return FOCUS_AREA_SIZE_DEFAULT;
}
private int getFocusMeteringAreaWeight() {
return FOCUS_METERING_AREA_WEIGHT_DEFAULT;
}
private void resetFocus(final boolean success, final Camera camera) { private void resetFocus(final boolean success, final Camera camera) {
mFocusHandler.removeCallbacksAndMessages(null); mFocusHandler.removeCallbacksAndMessages(null);
@ -730,30 +718,45 @@ class Camera1 extends CameraImpl {
} }
private Rect calculateFocusArea(float x, float y) { private List<Camera.Area> computeMeteringAreas(double viewClickX, double viewClickY) {
int buffer = getFocusAreaSize() / 2;
int centerX = calculateCenter(x, mPreview.getView().getWidth(), buffer); // Event came in view coordinates. As far as I know, we must rotate to sensor coordinates.
int centerY = calculateCenter(y, mPreview.getView().getHeight(), buffer); // First, rescale to the -1000 ... 1000 range.
return new Rect( int displayToSensor = -computeSensorToDisplayOffset();
centerX - buffer, double viewWidth = mPreview.getView().getWidth();
centerY - buffer, double viewHeight = mPreview.getView().getHeight();
centerX + buffer, viewClickX = -1000d + (viewClickX / viewWidth) * 2000d;
centerY + buffer viewClickY = -1000d + (viewClickY / viewHeight) * 2000d;
);
// Apply rotation to this point.
// https://academo.org/demos/rotation-about-point/
double theta = ((double) displayToSensor) * Math.PI / 180;
double sensorClickX = viewClickX * Math.cos(theta) - viewClickY * Math.sin(theta);
double sensorClickY = viewClickX * Math.sin(theta) + viewClickY * Math.cos(theta);
Log.e(TAG, "viewClickX:"+viewClickX+", viewClickY:"+viewClickY);
Log.e(TAG, "sensorClickX:"+sensorClickX+", sensorClickY:"+sensorClickY);
// Compute the rect bounds.
Rect rect1 = computeMeteringArea(sensorClickX, sensorClickY, 150d);
int weight1 = 1000; // 150 * 150 * 1000 = more than 10.000.000
Rect rect2 = computeMeteringArea(sensorClickX, sensorClickY, 300d);
int weight2 = 100; // 300 * 300 * 100 = 9.000.000
List<Camera.Area> list = new ArrayList<>(2);
list.add(new Camera.Area(rect1, weight1));
list.add(new Camera.Area(rect2, weight2));
return list;
} }
private static int calculateCenter(float coord, int dimen, int buffer) { private Rect computeMeteringArea(double centerX, double centerY, double size) {
int normalized = (int) ((coord / dimen) * 2000 - 1000); double delta = size/2d;
if (Math.abs(normalized) + buffer > 1000) { int top = (int) Math.max(centerY - delta, -1000);
if (normalized > 0) { int bottom = (int) Math.min(centerY + delta, 1000);
return 1000 - buffer; int left = (int) Math.max(centerX - delta, -1000);
} else { int right = (int) Math.min(centerX + delta, 1000);
return -1000 + buffer; // Log.e(TAG, "top:"+top+", left:"+left+", bottom:"+bottom+", right:"+right);
} return new Rect(left, top, right, bottom);
} else {
return normalized;
}
} }

Loading…
Cancel
Save