Fix bug with startFocus before camera started

pull/1/head
Mattia Iavarone 7 years ago
parent 7c219484af
commit 3e98daa26b
  1. 21
      README.md
  2. 39
      camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
  3. 6
      camerakit/src/main/java/com/flurgle/camerakit/FocusMarkerLayout.java
  4. 26
      camerakit/src/main/java/com/flurgle/camerakit/PinchToZoomLayout.java

@ -1,5 +1,5 @@
*A fork of [Dylan McIntyre's CameraKit-Android library](https://github.com/gogopop/CameraKit-Android), originally a fork of [Google's CameraView library](https://github.com/google/cameraview). The library at this point has been completely rewritten and refactored. See [below](#roadmap) for a list of what was done. Feel free to open issues with suggestions or contribute.* *A fork of [Dylan McIntyre's CameraKit-Android library](https://github.com/gogopop/CameraKit-Android), originally a fork of [Google's CameraView library](https://github.com/google/cameraview). The library at this point has been completely rewritten and refactored. See [below](#roadmap) for a list of what was done. This works better than any other library I have tried, and I would be grateful for any issue, suggestion or contribution.*
# CameraKit # CameraKit
@ -42,20 +42,19 @@ Please read the javadocs in code if you have any doubt about the usage of a cert
- Seamless image and video capturing, even within the same session - Seamless image and video capturing, even within the same session
- System permission handling - System permission handling
- Dynamic sizing behavior - Dynamic sizing behavior
- Create a `CameraView` of any size (not just presets!) - Create a `CameraView` of **any** size
- Center inside or center crop behaviors - Center inside or center crop behaviors
- Automatic output cropping to match your `CameraView` bounds - Automatic output cropping to match your `CameraView` bounds
- Built-in tap to focus - Built-in tap to focus
- Built-in pinch to zoom - Built-in pinch to zoom
- Built-in grid drawing (3x3, 4x4, golden ratio) - Built-in grid drawing
- Control the camera parameters via XML or programmatically
- Multiple capture methods - Multiple capture methods
- Take high-resolution pictures with `capturePicture` - Take high-resolution pictures with `capturePicture`
- Take quick snapshots as a freeze frame of the preview with `captureSnapshot` (similar to SnapChat and Instagram) - Take quick snapshots as a freeze frame of the preview with `captureSnapshot` (similar to Snapchat and Instagram)
- `CameraUtils` to help with Bitmaps and orientations - `CameraUtils` to help with Bitmaps and orientations
- EXIF support - Metadata support for pictures and videos
- Automatically detected orientation tag - Automatically detected orientation tags
- Plug in location tags with `CameraView.setLocation(double, double)` to pictures and videos - Plug in location tags with `setLocation()` API
## Setup ## Setup
@ -405,8 +404,12 @@ These are still things that need to be done, off the top of my head:
- [x] replace setCameraListener() with addCameraListener() - [x] replace setCameraListener() with addCameraListener()
- [x] better threading, for example ensure callbacks are called in the ui thread - [x] better threading, for example ensure callbacks are called in the ui thread
- [x] pinch to zoom support - [x] pinch to zoom support
- [ ] exposure correction APIs - [ ] change demo app icon
- [ ] refactor package name
- [ ] `Camera2` integration - [ ] `Camera2` integration
- [ ] publish to bintray
- [ ] exposure correction APIs
- [ ] attach operations (e.g. zoom, exposure correction) to vertical swipes or horizontal swipes
- [ ] check onPause / onStop / onSaveInstanceState consistency - [ ] check onPause / onStop / onSaveInstanceState consistency
- [ ] add a `setPreferredAspectRatio` API to choose the capture size. Preview size will adapt, and then, if let free, the CameraView will adapt as well - [ ] add a `setPreferredAspectRatio` API to choose the capture size. Preview size will adapt, and then, if let free, the CameraView will adapt as well
- [ ] animate grid lines similar to stock camera app - [ ] animate grid lines similar to stock camera app

@ -86,7 +86,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
private int mJpegQuality; private int mJpegQuality;
private boolean mCropOutput; private boolean mCropOutput;
private int mDisplayOffset;
private CameraCallbacks mCameraCallbacks; private CameraCallbacks mCameraCallbacks;
private OrientationHelper mOrientationHelper; private OrientationHelper mOrientationHelper;
private CameraController mCameraController; private CameraController mCameraController;
@ -148,7 +147,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mOrientationHelper = new OrientationHelper(context) { mOrientationHelper = new OrientationHelper(context) {
@Override @Override
public void onDisplayOffsetChanged(int displayOffset) { public void onDisplayOffsetChanged(int displayOffset) {
mDisplayOffset = displayOffset;
mCameraController.onDisplayOffset(displayOffset); mCameraController.onDisplayOffset(displayOffset);
mPreviewImpl.onDisplayOffset(displayOffset); mPreviewImpl.onDisplayOffset(displayOffset);
} }
@ -325,15 +323,25 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
// And dispatch to everyone. // Enable/Disable what needs to be enabled/disabled (because CameraOptions is involved).
// Pinch-to-zoom actually does not need it because it won't draw anything either way.
// Grid-lines does not need it because grid modes are always supported.
// Why don't we do it just once? Because shit happens when setFocus() is called before camera open.
// We don't know if focus is supported at that point.
CameraOptions options = mCameraController.getCameraOptions();
mFocusMarkerLayout.enable(mCameraController.getFocus() == CameraConstants.FOCUS_TAP_WITH_MARKER);
mPinchToZoomLayout.enable(options != null && options.isZoomSupported());
// Pinch to zoom gesture...
if (mPinchToZoomLayout.onTouchEvent(event)) { if (mPinchToZoomLayout.onTouchEvent(event)) {
// For pinch-to-zoom.
float zoom = mPinchToZoomLayout.getZoom(); float zoom = mPinchToZoomLayout.getZoom();
boolean did = setZoom(zoom); PointF[] fingers = mPinchToZoomLayout.getPoints();
if (did) mCameraCallbacks.dispatchOnZoomChanged(zoom, mPinchToZoomLayout.getPoints()); mCameraController.setZoom(zoom); // <- We know this is successful, due to mPinchToZoomLayout.enable() above.
mCameraCallbacks.dispatchOnZoomChanged(zoom, fingers);
// Focus gesture...
} else if (mFocusMarkerLayout.onTouchEvent(event)) { } else if (mFocusMarkerLayout.onTouchEvent(event)) {
// For drawing focus marker. startFocus(event.getX(), event.getY());
startFocus(event.getX(), event.getY()); // For focus behavior.
} }
return true; return true;
} }
@ -502,22 +510,22 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
/** /**
* Sets a zoom value. This is not guaranteed to be supported by the current device. * Sets a zoom value. This is not guaranteed to be supported by the current device,
* Look at the returned boolean to check. * but you can take a look at {@link CameraOptions#isZoomSupported()}.
* This will have no effect if called before the camera is opened.
*
* Zoom value should be >= 0 and <= 1, where 1 will be the maximum available zoom. * Zoom value should be >= 0 and <= 1, where 1 will be the maximum available zoom.
* *
* @param zoom value in [0,1] * @param zoom value in [0,1]
*/ */
public boolean setZoom(float zoom) { public void setZoom(float zoom) {
if (zoom < 0 || zoom > 1) { if (zoom < 0 || zoom > 1) {
throw new IllegalArgumentException("Zoom value should be >= 0 and <= 1"); throw new IllegalArgumentException("Zoom value should be >= 0 and <= 1");
} }
if (mCameraController.setZoom(zoom)) { if (mCameraController.setZoom(zoom)) {
// Notify PinchToZoomLayout, just in case the call came from outside. // Notify PinchToZoomLayout, just in case the call came from outside.
mPinchToZoomLayout.onExternalZoom(zoom); mPinchToZoomLayout.onExternalZoom(zoom);
return true;
} }
return false;
} }
@ -712,11 +720,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
* @param focus a Focus value. * @param focus a Focus value.
*/ */
public void setFocus(@Focus int focus) { public void setFocus(@Focus int focus) {
// TODO we are not sure this focus is supported at this point, yet we enable the layout!
mFocusMarkerLayout.setEnabled(focus == CameraConstants.FOCUS_TAP_WITH_MARKER);
if (focus == CameraConstants.FOCUS_TAP_WITH_MARKER) {
focus = CameraConstants.FOCUS_TAP;
}
mCameraController.setFocus(focus); mCameraController.setFocus(focus);
} }

@ -16,6 +16,7 @@ class FocusMarkerLayout extends FrameLayout {
private FrameLayout mFocusMarkerContainer; private FrameLayout mFocusMarkerContainer;
private ImageView mFill; private ImageView mFill;
private boolean mEnabled;
public FocusMarkerLayout(@NonNull Context context) { public FocusMarkerLayout(@NonNull Context context) {
this(context, null); this(context, null);
@ -33,7 +34,7 @@ class FocusMarkerLayout extends FrameLayout {
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction(); int action = event.getAction();
if (action == MotionEvent.ACTION_UP && isEnabled()) { if (action == MotionEvent.ACTION_UP && mEnabled) {
focus(event.getX(), event.getY()); focus(event.getX(), event.getY());
return true; return true;
} }
@ -79,4 +80,7 @@ class FocusMarkerLayout extends FrameLayout {
} }
public void enable(boolean enable) {
mEnabled = enable;
}
} }

@ -13,8 +13,9 @@ import android.view.View;
class PinchToZoomLayout extends View { class PinchToZoomLayout extends View {
private ScaleGestureDetector detector; private ScaleGestureDetector mDetector;
private boolean notify; private boolean mNotify;
private boolean mEnabled;
@ZoomMode private int mZoomMode; @ZoomMode private int mZoomMode;
private float mZoom = 0; private float mZoom = 0;
private PointF[] mPoints = new PointF[]{ private PointF[] mPoints = new PointF[]{
@ -28,10 +29,10 @@ class PinchToZoomLayout extends View {
public PinchToZoomLayout(@NonNull Context context, @Nullable AttributeSet attrs) { public PinchToZoomLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs); super(context, attrs);
detector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() { mDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@Override @Override
public boolean onScale(ScaleGestureDetector detector) { public boolean onScale(ScaleGestureDetector detector) {
notify = true; mNotify = true;
mZoom += ((detector.getScaleFactor() - 1) * 2); mZoom += ((detector.getScaleFactor() - 1) * 2);
if (mZoom < 0) mZoom = 0; if (mZoom < 0) mZoom = 0;
if (mZoom > 1) mZoom = 1; if (mZoom > 1) mZoom = 1;
@ -40,7 +41,7 @@ class PinchToZoomLayout extends View {
}); });
if (Build.VERSION.SDK_INT >= 19) { if (Build.VERSION.SDK_INT >= 19) {
detector.setQuickScaleEnabled(false); mDetector.setQuickScaleEnabled(false);
} }
} }
@ -68,19 +69,20 @@ class PinchToZoomLayout extends View {
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
if (mZoomMode != CameraConstants.ZOOM_PINCH) return false; if (mZoomMode != CameraConstants.ZOOM_PINCH) return false;
if (!mEnabled) return false;
// Reset the notify flag on a new gesture. // Reset the mNotify flag on a new gesture.
// This is to ensure that the notify flag stays on until the // This is to ensure that the mNotify flag stays on until the
// previous gesture ends. // previous gesture ends.
if (event.getAction() == MotionEvent.ACTION_DOWN) { if (event.getAction() == MotionEvent.ACTION_DOWN) {
notify = false; mNotify = false;
} }
// Let's see if we detect something. This will call onScale(). // Let's see if we detect something. This will call onScale().
detector.onTouchEvent(event); mDetector.onTouchEvent(event);
// Keep notifying CameraView as long as the gesture goes. // Keep notifying CameraView as long as the gesture goes.
if (notify) { if (mNotify) {
mPoints[0].x = event.getX(0); mPoints[0].x = event.getX(0);
mPoints[0].y = event.getY(0); mPoints[0].y = event.getY(0);
if (event.getPointerCount() > 1) { if (event.getPointerCount() > 1) {
@ -91,4 +93,8 @@ class PinchToZoomLayout extends View {
} }
return false; return false;
} }
public void enable(boolean enable) {
mEnabled = enable;
}
} }

Loading…
Cancel
Save