diff --git a/README.md b/README.md index 0c163116..0ba24c5b 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 - System permission handling - Dynamic sizing behavior - - Create a `CameraView` of any size (not just presets!) + - Create a `CameraView` of **any** size - Center inside or center crop behaviors - Automatic output cropping to match your `CameraView` bounds - Built-in tap to focus - Built-in pinch to zoom -- Built-in grid drawing (3x3, 4x4, golden ratio) -- Control the camera parameters via XML or programmatically +- Built-in grid drawing - Multiple capture methods - 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 -- EXIF support - - Automatically detected orientation tag - - Plug in location tags with `CameraView.setLocation(double, double)` to pictures and videos +- Metadata support for pictures and videos + - Automatically detected orientation tags + - Plug in location tags with `setLocation()` API ## 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] better threading, for example ensure callbacks are called in the ui thread - [x] pinch to zoom support -- [ ] exposure correction APIs +- [ ] change demo app icon +- [ ] refactor package name - [ ] `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 - [ ] 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 diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java index e50752b1..d73b40f8 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java @@ -86,7 +86,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver { private int mJpegQuality; private boolean mCropOutput; - private int mDisplayOffset; private CameraCallbacks mCameraCallbacks; private OrientationHelper mOrientationHelper; private CameraController mCameraController; @@ -148,7 +147,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver { mOrientationHelper = new OrientationHelper(context) { @Override public void onDisplayOffsetChanged(int displayOffset) { - mDisplayOffset = displayOffset; mCameraController.onDisplayOffset(displayOffset); mPreviewImpl.onDisplayOffset(displayOffset); } @@ -325,15 +323,25 @@ public class CameraView extends FrameLayout implements LifecycleObserver { @Override 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)) { - // For pinch-to-zoom. float zoom = mPinchToZoomLayout.getZoom(); - boolean did = setZoom(zoom); - if (did) mCameraCallbacks.dispatchOnZoomChanged(zoom, mPinchToZoomLayout.getPoints()); + PointF[] fingers = 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)) { - // For drawing focus marker. - startFocus(event.getX(), event.getY()); // For focus behavior. + startFocus(event.getX(), event.getY()); } 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. - * Look at the returned boolean to check. + * Sets a zoom value. This is not guaranteed to be supported by the current device, + * 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. * * @param zoom value in [0,1] */ - public boolean setZoom(float zoom) { + public void setZoom(float zoom) { if (zoom < 0 || zoom > 1) { throw new IllegalArgumentException("Zoom value should be >= 0 and <= 1"); } if (mCameraController.setZoom(zoom)) { // Notify PinchToZoomLayout, just in case the call came from outside. mPinchToZoomLayout.onExternalZoom(zoom); - return true; } - return false; } @@ -712,11 +720,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver { * @param focus a Focus value. */ 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); } diff --git a/camerakit/src/main/java/com/flurgle/camerakit/FocusMarkerLayout.java b/camerakit/src/main/java/com/flurgle/camerakit/FocusMarkerLayout.java index 78706ec0..ebff53eb 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/FocusMarkerLayout.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/FocusMarkerLayout.java @@ -16,6 +16,7 @@ class FocusMarkerLayout extends FrameLayout { private FrameLayout mFocusMarkerContainer; private ImageView mFill; + private boolean mEnabled; public FocusMarkerLayout(@NonNull Context context) { this(context, null); @@ -33,7 +34,7 @@ class FocusMarkerLayout extends FrameLayout { @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); - if (action == MotionEvent.ACTION_UP && isEnabled()) { + if (action == MotionEvent.ACTION_UP && mEnabled) { focus(event.getX(), event.getY()); return true; } @@ -79,4 +80,7 @@ class FocusMarkerLayout extends FrameLayout { } + public void enable(boolean enable) { + mEnabled = enable; + } } diff --git a/camerakit/src/main/java/com/flurgle/camerakit/PinchToZoomLayout.java b/camerakit/src/main/java/com/flurgle/camerakit/PinchToZoomLayout.java index f4810a9a..8af3bb82 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/PinchToZoomLayout.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/PinchToZoomLayout.java @@ -13,8 +13,9 @@ import android.view.View; class PinchToZoomLayout extends View { - private ScaleGestureDetector detector; - private boolean notify; + private ScaleGestureDetector mDetector; + private boolean mNotify; + private boolean mEnabled; @ZoomMode private int mZoomMode; private float mZoom = 0; private PointF[] mPoints = new PointF[]{ @@ -28,10 +29,10 @@ class PinchToZoomLayout extends View { public PinchToZoomLayout(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); - detector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() { + mDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() { @Override public boolean onScale(ScaleGestureDetector detector) { - notify = true; + mNotify = true; mZoom += ((detector.getScaleFactor() - 1) * 2); if (mZoom < 0) mZoom = 0; if (mZoom > 1) mZoom = 1; @@ -40,7 +41,7 @@ class PinchToZoomLayout extends View { }); if (Build.VERSION.SDK_INT >= 19) { - detector.setQuickScaleEnabled(false); + mDetector.setQuickScaleEnabled(false); } } @@ -68,19 +69,20 @@ class PinchToZoomLayout extends View { @Override public boolean onTouchEvent(MotionEvent event) { if (mZoomMode != CameraConstants.ZOOM_PINCH) return false; + if (!mEnabled) return false; - // Reset the notify flag on a new gesture. - // This is to ensure that the notify flag stays on until the + // Reset the mNotify flag on a new gesture. + // This is to ensure that the mNotify flag stays on until the // previous gesture ends. if (event.getAction() == MotionEvent.ACTION_DOWN) { - notify = false; + mNotify = false; } // 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. - if (notify) { + if (mNotify) { mPoints[0].x = event.getX(0); mPoints[0].y = event.getY(0); if (event.getPointerCount() > 1) { @@ -91,4 +93,8 @@ class PinchToZoomLayout extends View { } return false; } + + public void enable(boolean enable) { + mEnabled = enable; + } }