diff --git a/README.md b/README.md
index 41a58be3..908bcf19 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
#####Originally a fork of [Google's CameraView library](https://github.com/google/cameraview).
-CameraKit is an extraordinarily easy to use utility to work with the infamous Android Camera and Camera2 APIs. Built by [Dylan McIntyre](https://github.com/dwillmc).
+CameraKit is an extraordinarily easy to use utility to work with the infamous Android Camera and Camera2 APIs. Built by [Dylan McIntyre](https://github.com/dwillmc).
Try out all the unique features using the CameraKit Demo from the Google Play store!
@@ -20,26 +20,24 @@ Try out all the unique features using the CameraKit Demo from the Google Play st
- [Usage](#usage)
- [Events](#events)
- [Extra Attributes](#extra-attributes)
- - [`ckCropOutput`](#ckcropoutput)
- [`ckFacing`](#ckfacing)
- [`ckFlash`](#ckflash)
- - [`ckCaptureMode`](#ckcapturemode)
- - [`ckPinchToZoom`](#ckpinchtozoom)
- - [`ckTapToFocus`](#cktaptofocus)
- - [`ckAutoFocus`](#ckautofocus)
- - [`ckCaptureSize`](#ckcapturesize)
- - [`ckJpegCompression`](#ckjpegcompression)
+ - [`ckFocus`](#ckfocus)
+ - [`ckMethod`](#ckmethod)
+ - [`ckZoom`](#ckzoom)
+ - [`ckCropOutput`](#ckcropoutput)
+ - [`ckJpegQuality`](#ckjpegquality)
- [Capturing Images](#capturing-images)
- [Capturing Video](#capturing-video)
- [Automatic Permissions Behavior](#automatic-permissions-behavior)
- [Dynamic Sizing Behavior](#dynamic-sizing-behavior)
- [Output Cropping](#output-cropping)
- [`adjustViewBounds`](#adjustviewbounds)
-- [Capture Mode Behavior](#capture-mode-behavior)
- - [Quality](#quality)
- - [Speed](#speed)
+- [Capture Methods](#capture-methods)
+ - [Standard](#standard)
+ - [Still](#still)
- [Auto](#auto)
-- [Tap To Focus](#tap-to-focus)
+- [Focus](#focus)
- [Credits](#credits)
- [License](#license)
@@ -51,9 +49,9 @@ Try out all the unique features using the CameraKit Demo from the Google Play st
- Automatic preview scaling.
- Create a `CameraView` of any size (not just presets!).
- Automatic output cropping to match your `CameraView` bounds.
-- Multiple capture modes.
- - `PICTURE_MODE_STANDARD`: an image captured normally using the camera APIs.
- - `PICTURE_MODE_STILL`: a freeze frame of the `CameraView` preview (similar to SnapChat and Instagram) for devices with slower cameras.
+- Multiple capture methods.
+ - `METHOD_STANDARD`: an image captured normally using the camera APIs.
+ - `METHOD_STILL`: a freeze frame of the `CameraView` preview (similar to SnapChat and Instagram) for devices with slower cameras.
- Automatic picture mode determination based on measured speed.
- Built-in tap to focus and auto focus.
- Built-in pinch to zoom.
@@ -74,7 +72,8 @@ To use CameraKit, simply add a `CameraView` to your layout:
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true" />
```
Make sure you override `onResume` and `onPause` in your activity, and make calls respectively to `CameraView.start()` and `CameraView.stop()`.
@@ -119,7 +118,7 @@ camera.setCameraListener(new CameraListener() {
public void onVideoTaken(File video) {
super.onVideoTaken(video);
}
-
+
});
```
@@ -129,25 +128,17 @@ camera.setCameraListener(new CameraListener() {
+ camerakit:ckFocus="continuous"
+ camerakit:ckMethod="standard"
+ camerakit:ckZoom="pinch"
+ camerakit:ckCropOutput="true"
+ camerakit:ckJpegQuality="100"
+ android:adjustViewBounds="true" />
```
-#### `ckCropOutput`
-
-| Value | Description |
-| --------------| -------------|
-| `true` | Crop the output image or video to only contain what can be seen on the `CameraView` preview. |
-| `false` | Output the full image or video regardless of what is visible on the `CameraView` preview. |
-
#### `ckFacing`
| Value | Description |
@@ -163,44 +154,37 @@ camera.setCameraListener(new CameraListener() {
| `on` | Default `CameraView` flash to on. |
| `auto` | Default `CameraView` flash to automatic. |
-#### `ckCaptureMode`
-
-| Value | Description |
-| --------------| -------------|
-| `standard` | Use normal Android Camera API image capturing. |
-| `still` | Freeze the `CameraView` preview and grab a `Bitmap` of the frame. |
-| `auto` (coming soon) | Default picture mode to `standard`, but fallback to `still` if capturing is determined to be too slow. |
-
-#### `ckPinchToZoom`
+#### `ckFocus`
| Value | Description |
| --------------| -------------|
-| `true` | User can zoom using pinching gestures with their fingers. |
-| `false` | Default pinch to zoom behavior disabled. |
+| `off` | Tap to focus is enabled and a visible focus circle appears when tapped, similar to the Android built-in camera. |
+| `continuous` | Tap to focus is enabled, but no focus circle appears. |
+| `tap` | Tap to focus is off. |
-#### `ckTapToFocus`
+#### `ckMethod`
| Value | Description |
| --------------| -------------|
-| `visible` | Tap to focus is enabled and a visible focus circle appears when tapped, similar to the Android built-in camera. |
-| `invisible` | Tap to focus is enabled, but no focus circle appears. |
-| `off` | Tap to focus is off. |
+| `standard` | Use normal Android Camera API image capturing. |
+| `still` | Freeze the `CameraView` preview and grab a `Bitmap` of the frame. |
+| `auto` (coming soon) | Default picture mode to `standard`, but fallback to `still` if capturing is determined to be too slow. |
-#### `ckAutoFocus`
+#### `ckZoom`
| Value | Description |
| --------------| -------------|
-| `true` | Continuously allow the `CameraView` preview to adjust focus automatically. |
-| `false` | Never adjust focus during preview. |
+| `off` | User can zoom using pinching gestures with their fingers. |
+| `pinch` | User can zoom in and out using pinching gestures on the `CameraView`. |
-#### `ckCaptureSize`
+#### `ckCropOutput`
| Value | Description |
| --------------| -------------|
-| `n <= 0` | Capture at the highest quality possible. |
-| `n > 0` | Capture at a size of approximately `n` megapixels. |
+| `true` | Crop the output image or video to only contain what can be seen on the `CameraView` preview. |
+| `false` | Output the full image or video regardless of what is visible on the `CameraView` preview. |
-#### `ckJpegCompression`
+#### `ckJpegQuality`
| Value | Description |
| --------------| -------------|
@@ -209,20 +193,20 @@ camera.setCameraListener(new CameraListener() {
### Capturing Images
-To capture an image just call `CameraView.capturePicture()`. Make sure you setup a `CameraListener` to handle the image callback.
+To capture an image just call `CameraView.captureImage()`. Make sure you setup a `CameraListener` to handle the image callback.
```java
camera.setCameraListener(new CameraListener() {
@Override
public void onPictureTaken(byte[] picture) {
super.onPictureTaken(picture);
-
+
// Create a bitmap
Bitmap result = BitmapFactory.decodeByteArray(picture, 0, picture.length);
}
});
-camera.takePicture();
+camera.captureImage();
```
### Capturing Video
@@ -234,7 +218,7 @@ camera.setCameraListener(new CameraListener() {
@Override
public void onVideoTaken(File video) {
super.onVideoTaken(video);
- // The File parameter is an MP4 file.
+ // The File parameter is an MP4 file.
}
});
@@ -251,7 +235,7 @@ camera.postDelayed(new Runnable() {
You can handle permissions yourself in whatever way you want, but if you make a call to `CameraView.start()` without the `android.permission.CAMERA` permission, an exception would normally be thrown and your app would crash.
-With CameraKit, we will automatically prompt for the `android.permission.CAMERA` permission if it's not available. If you want to handle it yourself, just make sure you dont call `CameraView.start()` until you acquire the permissions.
+With CameraKit, we will automatically prompt for the `android.permission.CAMERA` permission if it's not available. If you want to handle it yourself, just make sure you don't call `CameraView.start()` until you acquire the permissions.
![Permissions behavior gif](.repo/permissions.gif)
@@ -271,35 +255,35 @@ When you capture output you can either capture everything - even what is not vis
You can use a mix of a fixed dimension (a set value or `match_parent`) as well as `wrap_content`. When you do this make sure you set `android:adjustViewBounds="true"` on the `CameraView`.
-When you do this the dimension set to `wrap_content` will automatically align with the true aspect ratio of the preview surface. In this case the whole preview will be visible.
+When you do this the dimension set to `wrap_content` will automatically align with the true aspect ratio of the preview surface. In this case the whole preview will be visible with no cropping.
-## Capture Mode Behavior
+## Capture Methods
We decided to add multiple capture modes to CameraKit to allow you to give a better image capturing experience to users with slower cameras when appropriate.
-See [`ckPictureMode`](#ckpicturemode) above for usage.
+See [`ckMethod`](#ckmethod) above for usage.
-### Quality
+### Standard
-When you use `PICTURE_MODE_QUALITY` (`camerakit:ckPictureMode="quality"`), images will be captured using the normal camera API capture method using the shutter.
+When you use `METHOD_STANDARD` (`camerakit:ckMethod="standard"`), images will be captured using the normal camera API capture method using the shutter.
[Insert GIF]
-### Speed
+### Still
-When you use `PICTURE_MODE_SPEED` (`camerakit:ckPictureMode="speed"`), images will be captured by grabbing a single frame from the preview. This behavior is the same as SnapChat and Instagram. This method has a higher rate of motion blur but can be a better experience for users with slower cameras.
+When you use `METHOD_STILL` (`camerakit:ckMethod="still"`), images will be captured by grabbing a single frame from the preview. This behavior is the same as SnapChat and Instagram. This method has a higher rate of motion blur but can be a better experience for users with slower cameras.
[Insert GIF]
### Auto
-When you use `PICTURE_MODE_AUTO` (`camerakit:ckPictureMode="speed"`), images will be first be captured using the [quality](#quality) method. If capture consistently takes a long amount of time, the picture mode will fallback to [speed](#speed).
+When you use `METHOD_AUTO` (`camerakit:ckMethod="auto"`), images will be first be captured using the [standard](#standard) method. If capture consistently takes a long amount of time, the picture mode will fallback to [still](#still) capture.
[Insert GIF]
-## Tap To Focus
+## Focus
-Along with the always on auto-focus, you can enable tap to focus in your `CameraView`. See [`ckTapToFocus`](#cktaptofocus) for usage. You have the option of having it on with a visible focus marker, on with no marker, or off.
+Along with the always on auto-focus, you can enable tap to focus in your `CameraView`. See [`ckFocus`](#ckFocus) for usage. You have the option of having it on with a visible focus marker, on with no marker, or off.
[Insert GIF]
diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
index 9e48cc94..0cab6593 100644
--- a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
+++ b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
@@ -11,6 +11,13 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
+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;
+import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_TAP;
+import static com.flurgle.camerakit.CameraKit.Constants.METHOD_STANDARD;
+import static com.flurgle.camerakit.CameraKit.Constants.METHOD_STILL;
+
@SuppressWarnings("deprecation")
public class Camera1 extends CameraImpl {
@@ -21,10 +28,22 @@ public class Camera1 extends CameraImpl {
private Size mPreviewSize;
private Size mCaptureSize;
+ private int mDisplayOrientation;
+
+ @Facing
private int mFacing;
+
+ @Flash
private int mFlash;
- private boolean mContinuousFocus;
- private int mDisplayOrientation;
+
+ @Focus
+ private int mFocus;
+
+ @Method
+ private int mMethod;
+
+ @Zoom
+ private int mZoom;
Camera1(CameraListener callback, PreviewImpl preview) {
super(callback, preview);
@@ -57,6 +76,11 @@ public class Camera1 extends CameraImpl {
releaseCamera();
}
+ @Override
+ void setDisplayOrientation(int displayOrientation) {
+ this.mDisplayOrientation = displayOrientation;
+ }
+
@Override
void setFacing(@Facing int facing) {
int internalFacing = new ConstantMapper.Facing(facing).map();
@@ -81,7 +105,7 @@ public class Camera1 extends CameraImpl {
@Override
void setFlash(@Flash int flash) {
- if (isCameraOpened()) {
+ if (mCameraParameters != null) {
List flashes = mCameraParameters.getSupportedFlashModes();
String internalFlash = new ConstantMapper.Flash(flash).map();
if (flashes != null && flashes.contains(internalFlash)) {
@@ -91,7 +115,7 @@ public class Camera1 extends CameraImpl {
String currentFlash = new ConstantMapper.Flash(mFlash).map();
if (flashes == null || !flashes.contains(currentFlash)) {
mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
- mFlash = CameraKit.Constants.FLASH_OFF;
+ mFlash = FLASH_OFF;
}
}
@@ -102,61 +126,76 @@ public class Camera1 extends CameraImpl {
}
@Override
- void setContinuousFocus(boolean continuousFocus) {
- this.mContinuousFocus = continuousFocus;
- if (mCameraParameters != null) {
- final List modes = mCameraParameters.getSupportedFocusModes();
- if (mContinuousFocus && modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
- mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
- } else if (modes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) {
- mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
- } else if (modes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) {
- mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
- } else {
- mCameraParameters.setFocusMode(modes.get(0));
- }
- }
- }
+ void setFocus(@Focus int focus) {
+ this.mFocus = focus;
+ switch (focus) {
+ case FOCUS_CONTINUOUS:
+ if (mCameraParameters != null) {
+ final List modes = mCameraParameters.getSupportedFocusModes();
+ if (modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
+ mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ } else {
+ setFocus(FOCUS_OFF);
+ }
+ }
+ break;
- @Override
- void setDisplayOrientation(int displayOrientation) {
- this.mDisplayOrientation = displayOrientation;
- }
+ case FOCUS_TAP:
+ setFocus(FOCUS_CONTINUOUS);
+ break;
- @Override
- void focus() {
- mCamera.autoFocus(null);
+ case FOCUS_OFF:
+ if (mCameraParameters != null) {
+ final List modes = mCameraParameters.getSupportedFocusModes();
+ if (modes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) {
+ mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
+ } else if (modes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) {
+ mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
+ } else {
+ mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
+ }
+ }
+ break;
+ }
}
@Override
- void zoom(float percentZoom) {
-
+ void setMethod(@Method int method) {
+ this.mMethod = method;
}
@Override
- void captureStandard() {
- mCamera.takePicture(null, null, null, new Camera.PictureCallback() {
- @Override
- public void onPictureTaken(byte[] data, Camera camera) {
- mCameraListener.onPictureTaken(data);
- camera.startPreview();
- }
- });
+ void setZoom(@Zoom int zoom) {
+ this.mZoom = zoom;
}
@Override
- void captureStill() {
- mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
- @Override
- public void onPreviewFrame(byte[] data, Camera camera) {
- new Thread(new ProcessStillTask(data, camera, mCameraInfo, new ProcessStillTask.OnStillProcessedListener() {
+ void captureImage() {
+ switch (mMethod) {
+ case METHOD_STANDARD:
+ mCamera.takePicture(null, null, null, new Camera.PictureCallback() {
@Override
- public void onStillProcessed(final YuvImage yuv) {
- mCameraListener.onPictureTaken(yuv);
+ public void onPictureTaken(byte[] data, Camera camera) {
+ mCameraListener.onPictureTaken(data);
+ camera.startPreview();
}
- })).start();
- }
- });
+ });
+ break;
+
+ case METHOD_STILL:
+ mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ new Thread(new ProcessStillTask(data, camera, mCameraInfo, new ProcessStillTask.OnStillProcessedListener() {
+ @Override
+ public void onStillProcessed(final YuvImage yuv) {
+ mCameraListener.onPictureTaken(yuv);
+ }
+ })).start();
+ }
+ });
+ break;
+ }
}
@Override
@@ -297,7 +336,7 @@ public class Camera1 extends CameraImpl {
+ (mFacing == CameraKit.Constants.FACING_FRONT ? 180 : 0)
);
- setContinuousFocus(mContinuousFocus);
+ setFocus(mFocus);
setFlash(mFlash);
mCamera.setParameters(mCameraParameters);
diff --git a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java
index 3d01c0d3..419852f4 100644
--- a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java
+++ b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java
@@ -17,42 +17,37 @@ class Camera2 extends CameraImpl {
}
@Override
- void setFacing(@Facing int facing) {
-
- }
-
- @Override
- void setFlash(@Flash int flash) {
+ void setDisplayOrientation(int displayOrientation) {
}
@Override
- void setContinuousFocus(boolean autoFocus) {
+ void setFacing(@Facing int facing) {
}
@Override
- void setDisplayOrientation(int displayOrientation) {
+ void setFlash(@Flash int flash) {
}
@Override
- void focus() {
+ void setFocus(@Focus int focus) {
}
@Override
- void zoom(float percentZoom) {
+ void setMethod(@Method int method) {
}
@Override
- void captureStandard() {
+ void setZoom(@Zoom int zoom) {
}
@Override
- void captureStill() {
+ void captureImage() {
}
diff --git a/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
index ade7ca15..80e6b8c5 100644
--- a/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
+++ b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
@@ -13,17 +13,15 @@ abstract class CameraImpl {
abstract void start();
abstract void stop();
- abstract void setFacing(@Facing int facing);
- abstract void setFlash(@Flash int flash);
- abstract void setContinuousFocus(boolean autoFocus);
-
abstract void setDisplayOrientation(int displayOrientation);
- abstract void focus();
- abstract void zoom(float percentZoom);
- abstract void captureStandard();
- abstract void captureStill();
+ abstract void setFacing(@Facing int facing);
+ abstract void setFlash(@Flash int flash);
+ abstract void setFocus(@Focus int focus);
+ abstract void setMethod(@Method int method);
+ abstract void setZoom(@Zoom int zoom);
+ abstract void captureImage();
abstract void startVideo();
abstract void endVideo();
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
index c08abbab..a580eb92 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
+++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
@@ -13,6 +13,8 @@ public class CameraKit {
public static class Constants {
+ public static final int PERMISSION_REQUEST_CAMERA = 16;
+
public static final int FACING_BACK = 0;
public static final int FACING_FRONT = 1;
@@ -20,15 +22,31 @@ public class CameraKit {
public static final int FLASH_ON = 1;
public static final int FLASH_AUTO = 2;
- public static final int CAPTURE_MODE_STANDARD = 0;
- public static final int CAPTURE_MODE_STILL = 1;
- public static final int PICTURE_MODE_AUTO = 2;
+ public static final int METHOD_STANDARD = 0;
+ public static final int METHOD_STILL = 1;
+ public static final int METHOD_AUTO = 2;
+
+ public static final int FOCUS_OFF = 0;
+ public static final int FOCUS_CONTINUOUS = 1;
+ public static final int FOCUS_TAP = 2;
- public static final int TAP_TO_FOCUS_VISIBLE = 0;
- public static final int TAP_TO_FOCUS_INVISIBLE = 1;
- public static final int TAP_TO_FOCUS_OFF = 2;
+ public static final int ZOOM_OFF = 0;
+ public static final int ZOOM_PINCH = 1;
}
+ static class Defaults {
+
+ static final int DEFAULT_FACING = Constants.FACING_BACK;
+ static final int DEFAULT_FLASH = Constants.FLASH_OFF;
+ static final int DEFAULT_FOCUS = Constants.FOCUS_OFF;
+ static final int DEFAULT_METHOD = Constants.METHOD_STANDARD;
+ static final int DEFAULT_ZOOM = Constants.ZOOM_OFF;
+
+ static final int DEFAULT_JPEG_QUALITY = 100;
+ static final boolean DEFAULT_CROP_OUTPUT = false;
+ static final boolean DEFAULT_ADJUST_VIEW_BOUNDS = false;
+
+ }
}
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
index a749b2a4..4ddae2d1 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
+++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
@@ -8,64 +8,47 @@ import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.YuvImage;
-import android.os.Parcel;
-import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.hardware.display.DisplayManagerCompat;
-import android.support.v4.os.ParcelableCompat;
-import android.support.v4.os.ParcelableCompatCreatorCallbacks;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.Display;
-import android.view.MotionEvent;
-import android.view.View;
import android.widget.FrameLayout;
import java.io.ByteArrayOutputStream;
import java.io.File;
-import static com.flurgle.camerakit.CameraKit.Constants.CAPTURE_MODE_STANDARD;
-import static com.flurgle.camerakit.CameraKit.Constants.CAPTURE_MODE_STILL;
import static com.flurgle.camerakit.CameraKit.Constants.FACING_BACK;
import static com.flurgle.camerakit.CameraKit.Constants.FACING_FRONT;
import static com.flurgle.camerakit.CameraKit.Constants.FLASH_AUTO;
import static com.flurgle.camerakit.CameraKit.Constants.FLASH_OFF;
import static com.flurgle.camerakit.CameraKit.Constants.FLASH_ON;
-import static com.flurgle.camerakit.CameraKit.Constants.TAP_TO_FOCUS_VISIBLE;
+import static com.flurgle.camerakit.CameraKit.Constants.METHOD_STANDARD;
public class CameraView extends FrameLayout {
- private static final int PERMISSION_REQUEST_CAMERA = 16;
- private static final int DEFAULT_CAPTURE_SIZE = -1;
- private static final int DEFAULT_JPEG_COMPRESSION = 100;
-
@Facing
private int mFacing;
@Flash
private int mFlash;
- @TapToFocus
- private int mTapToFocus;
-
- @CaptureMode
- private int mCaptureMode;
-
- private boolean mCropOutput;
-
- private boolean mContinuousFocus;
+ @Focus
+ private int mFocus;
- private float mCaptureSize;
+ @Method
+ private int mMethod;
- private int mJpegCompression;
+ @Zoom
+ private int mZoom;
+ private int mJpegQuality;
+ private boolean mCropOutput;
private boolean mAdjustViewBounds;
- private boolean mWaitingForPermission;
-
private CameraListenerMiddleWare mCameraListener;
private DisplayOrientationDetector mDisplayOrientationDetector;
@@ -79,8 +62,6 @@ public class CameraView extends FrameLayout {
@SuppressWarnings("all")
public CameraView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
-
-
if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
@@ -88,15 +69,15 @@ public class CameraView extends FrameLayout {
0, 0);
try {
- mFacing = a.getInteger(R.styleable.CameraView_ckFacing, FACING_BACK);
- mFlash = a.getInteger(R.styleable.CameraView_ckFlash, FLASH_OFF);
- mTapToFocus = a.getInteger(R.styleable.CameraView_ckTapToFocus, TAP_TO_FOCUS_VISIBLE);
- mCaptureMode = a.getInteger(R.styleable.CameraView_ckCaptureMode, CAPTURE_MODE_STANDARD);
- mCropOutput = a.getBoolean(R.styleable.CameraView_ckCropOutput, false);
- mContinuousFocus = a.getBoolean(R.styleable.CameraView_ckContinuousFocus, true);
- mCaptureSize = a.getFloat(R.styleable.CameraView_ckCaptureSize, DEFAULT_CAPTURE_SIZE);
- mJpegCompression = a.getInteger(R.styleable.CameraView_ckJpegCompression, DEFAULT_JPEG_COMPRESSION);
- mAdjustViewBounds = a.getBoolean(R.styleable.CameraView_android_adjustViewBounds, false);
+ mFacing = a.getInteger(R.styleable.CameraView_ckFacing, CameraKit.Defaults.DEFAULT_FACING);
+ mFlash = a.getInteger(R.styleable.CameraView_ckFlash, CameraKit.Defaults.DEFAULT_FLASH);
+ mFocus = a.getInteger(R.styleable.CameraView_ckFocus, CameraKit.Defaults.DEFAULT_FOCUS);
+ mMethod = a.getInteger(R.styleable.CameraView_ckMethod, CameraKit.Defaults.DEFAULT_METHOD);
+ mZoom = a.getInteger(R.styleable.CameraView_ckZoom, CameraKit.Defaults.DEFAULT_ZOOM);
+
+ mJpegQuality = a.getInteger(R.styleable.CameraView_ckJpegQuality, CameraKit.Defaults.DEFAULT_JPEG_QUALITY);
+ mCropOutput = a.getBoolean(R.styleable.CameraView_ckCropOutput, CameraKit.Defaults.DEFAULT_CROP_OUTPUT);
+ mAdjustViewBounds = a.getBoolean(R.styleable.CameraView_android_adjustViewBounds, CameraKit.Defaults.DEFAULT_ADJUST_VIEW_BOUNDS);
} finally {
a.recycle();
}
@@ -109,11 +90,9 @@ public class CameraView extends FrameLayout {
setFacing(mFacing);
setFlash(mFlash);
- setCaptureMode(mCaptureMode);
- setCropOutput(mCropOutput);
- setTapToFocus(mTapToFocus);
- setContinuousFocus(mContinuousFocus);
- setCaptureSize(mCaptureSize);
+ setFocus(mFocus);
+ setMethod(mMethod);
+ setZoom(mZoom);
mDisplayOrientationDetector = new DisplayOrientationDetector(context) {
@Override
@@ -140,30 +119,34 @@ public class CameraView extends FrameLayout {
}
@Override
- protected Parcelable onSaveInstanceState() {
- SavedState state = new SavedState(super.onSaveInstanceState());
- state.facing = mFacing;
- state.flash = mFlash;
- return state;
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- if (!(state instanceof SavedState)) {
- super.onRestoreInstanceState(state);
- return;
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (mAdjustViewBounds) {
+ Size previewSize = getPreviewSize();
+ if (getLayoutParams().width == LayoutParams.WRAP_CONTENT) {
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+ float ratio = (float) height / (float) previewSize.getWidth();
+ int width = (int) (previewSize.getHeight() * ratio);
+ super.onMeasure(
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ heightMeasureSpec
+ );
+ } else if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ float ratio = (float) width / (float) previewSize.getHeight();
+ int height = (int) (previewSize.getWidth() * ratio);
+ super.onMeasure(
+ widthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
+ );
+ }
+ } else {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
-
- SavedState ss = (SavedState) state;
- super.onRestoreInstanceState(ss.getSuperState());
- setFacing(ss.facing);
- setFlash(ss.flash);
}
public void start() {
int permissionCheck = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
- mWaitingForPermission = false;
mCameraImpl.start();
} else {
requestCameraPermission();
@@ -179,6 +162,34 @@ public class CameraView extends FrameLayout {
mCameraImpl.setFacing(facing);
}
+ public void setFlash(@Flash int flash) {
+ this.mFlash = flash;
+ mCameraImpl.setFlash(flash);
+ }
+
+ public void setFocus(@Focus int focus) {
+ this.mFocus = focus;
+ mCameraImpl.setFocus(mFocus);
+ }
+
+ public void setMethod(@Method int method) {
+ this.mMethod = method;
+ mCameraImpl.setMethod(mMethod);
+ }
+
+ public void setZoom(@Zoom int zoom) {
+ this.mZoom = zoom;
+ mCameraImpl.setZoom(mZoom);
+ }
+
+ public void setJpegQuality(int jpegQuality) {
+ this.mJpegQuality = jpegQuality;
+ }
+
+ public void setCropOutput(boolean cropOutput) {
+ this.mCropOutput = cropOutput;
+ }
+
@Facing
public int toggleFacing() {
switch (mFacing) {
@@ -194,11 +205,6 @@ public class CameraView extends FrameLayout {
return mFacing;
}
- public void setFlash(@Flash int flash) {
- this.mFlash = flash;
- mCameraImpl.setFlash(flash);
- }
-
@Flash
public int toggleFlash() {
switch (mFlash) {
@@ -218,50 +224,12 @@ public class CameraView extends FrameLayout {
return mFlash;
}
- public void setCaptureMode(@CaptureMode int captureMode) {
- this.mCaptureMode = captureMode;
- }
-
- @CaptureMode
- public int getCaptureMode() {
- return mCaptureMode;
- }
-
- public void setCropOutput(boolean cropOutput) {
- this.mCropOutput = cropOutput;
- }
-
- public void setTapToFocus(@TapToFocus int tapToFocus) {
- this.mTapToFocus = tapToFocus;
- if (tapToFocus == CameraKit.Constants.TAP_TO_FOCUS_OFF) {
- mPreviewImpl.getView().setOnTouchListener(null);
- } else {
- mPreviewImpl.getView().setOnTouchListener(mTapToFocusOnTouchListener);
- }
- }
-
- public void setContinuousFocus(boolean continuousFocus) {
- this.mContinuousFocus = continuousFocus;
- mCameraImpl.setContinuousFocus(continuousFocus);
- }
-
- public void setCaptureSize(float captureSize) {
- this.mCaptureSize = captureSize;
- }
-
public void setCameraListener(CameraListener cameraListener) {
this.mCameraListener.setCameraListener(cameraListener);
}
- public void capturePicture() {
- switch (mCaptureMode) {
- case CAPTURE_MODE_STANDARD:
- mCameraImpl.captureStandard();
- break;
- case CAPTURE_MODE_STILL:
- mCameraImpl.captureStill();
- break;
- }
+ public void captureImage() {
+ mCameraImpl.captureImage();
}
public void startRecordingVideo() {
@@ -291,74 +259,11 @@ public class CameraView extends FrameLayout {
}
if (activity != null) {
- ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CAMERA);
- mWaitingForPermission = true;
- }
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasWindowFocus) {
- super.onWindowFocusChanged(hasWindowFocus);
- if (mWaitingForPermission) {
- if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
- start();
- }
- }
- }
-
- private OnTouchListener mTapToFocusOnTouchListener = new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- mCameraImpl.focus();
- }
-
- return false;
- }
-
- };
-
-
- protected static class SavedState extends BaseSavedState {
-
- @Facing
- private int facing;
-
- @Flash
- private int flash;
-
- @SuppressWarnings("WrongConstant")
- public SavedState(Parcel source, ClassLoader loader) {
- super(source);
- facing = source.readInt();
- flash = source.readInt();
- }
-
- public SavedState(Parcelable superState) {
- super(superState);
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- super.writeToParcel(out, flags);
- out.writeInt(facing);
- out.writeInt(flash);
+ ActivityCompat.requestPermissions(
+ activity,
+ new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO},
+ CameraKit.Constants.PERMISSION_REQUEST_CAMERA);
}
-
- public static final Parcelable.Creator CREATOR = ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks() {
-
- @Override
- public SavedState createFromParcel(Parcel in, ClassLoader loader) {
- return new SavedState(in, loader);
- }
-
- @Override
- public SavedState[] newArray(int size) {
- return new SavedState[size];
- }
-
- });
-
}
private class CameraListenerMiddleWare extends CameraListener {
@@ -381,10 +286,10 @@ public class CameraView extends FrameLayout {
public void onPictureTaken(byte[] jpeg) {
super.onPictureTaken(jpeg);
if (mCropOutput) {
- int width = mCaptureMode == CAPTURE_MODE_STANDARD ? mCameraImpl.getCaptureResolution().getWidth() : mCameraImpl.getPreviewResolution().getWidth();
- int height = mCaptureMode == CAPTURE_MODE_STANDARD ? mCameraImpl.getCaptureResolution().getHeight() : mCameraImpl.getPreviewResolution().getHeight();
+ int width = mMethod == METHOD_STANDARD ? mCameraImpl.getCaptureResolution().getWidth() : mCameraImpl.getPreviewResolution().getWidth();
+ int height = mMethod == METHOD_STANDARD ? mCameraImpl.getCaptureResolution().getHeight() : mCameraImpl.getPreviewResolution().getHeight();
AspectRatio outputRatio = AspectRatio.of(getWidth(), getHeight());
- getCameraListener().onPictureTaken(new CenterCrop(jpeg, outputRatio, mJpegCompression).getJpeg());
+ getCameraListener().onPictureTaken(new CenterCrop(jpeg, outputRatio, mJpegQuality).getJpeg());
} else {
getCameraListener().onPictureTaken(jpeg);
}
@@ -395,10 +300,10 @@ public class CameraView extends FrameLayout {
super.onPictureTaken(yuv);
if (mCropOutput) {
AspectRatio outputRatio = AspectRatio.of(getWidth(), getHeight());
- getCameraListener().onPictureTaken(new CenterCrop(yuv, outputRatio, mJpegCompression).getJpeg());
+ getCameraListener().onPictureTaken(new CenterCrop(yuv, outputRatio, mJpegQuality).getJpeg());
} else {
ByteArrayOutputStream out = new ByteArrayOutputStream();
- yuv.compressToJpeg(new Rect(0, 0, yuv.getWidth(), yuv.getHeight()), mJpegCompression, out);
+ yuv.compressToJpeg(new Rect(0, 0, yuv.getWidth(), yuv.getHeight()), mJpegQuality, out);
getCameraListener().onPictureTaken(out.toByteArray());
}
}
diff --git a/camerakit/src/main/res/values/attrs.xml b/camerakit/src/main/res/values/attrs.xml
index c16347e0..a1029817 100644
--- a/camerakit/src/main/res/values/attrs.xml
+++ b/camerakit/src/main/res/values/attrs.xml
@@ -14,27 +14,33 @@
-
-
-
-
-
+
+
+
-
+
+
+
-
+
+
-
-
-
-
+
+
-
-
+
+
+
-
+
+
+
+
+
+
+
diff --git a/camerakit/src/main/types/com/flurgle/camerakit/Focus.java b/camerakit/src/main/types/com/flurgle/camerakit/Focus.java
index 790932fc..e186fcd2 100644
--- a/camerakit/src/main/types/com/flurgle/camerakit/Focus.java
+++ b/camerakit/src/main/types/com/flurgle/camerakit/Focus.java
@@ -5,11 +5,11 @@ import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import static com.flurgle.camerakit.CameraKit.Constants.TAP_TO_FOCUS_INVISIBLE;
-import static com.flurgle.camerakit.CameraKit.Constants.TAP_TO_FOCUS_OFF;
-import static com.flurgle.camerakit.CameraKit.Constants.TAP_TO_FOCUS_VISIBLE;
+import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_TAP;
+import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_OFF;
+import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_CONTINUOUS;
@Retention(RetentionPolicy.SOURCE)
-@IntDef({TAP_TO_FOCUS_VISIBLE, TAP_TO_FOCUS_INVISIBLE, TAP_TO_FOCUS_OFF})
+@IntDef({FOCUS_CONTINUOUS, FOCUS_TAP, FOCUS_OFF})
public @interface Focus {
}
\ No newline at end of file
diff --git a/camerakit/src/main/types/com/flurgle/camerakit/Method.java b/camerakit/src/main/types/com/flurgle/camerakit/Method.java
index e340286c..ba6d85b1 100644
--- a/camerakit/src/main/types/com/flurgle/camerakit/Method.java
+++ b/camerakit/src/main/types/com/flurgle/camerakit/Method.java
@@ -5,10 +5,10 @@ import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import static com.flurgle.camerakit.CameraKit.Constants.CAPTURE_MODE_STANDARD;
-import static com.flurgle.camerakit.CameraKit.Constants.CAPTURE_MODE_STILL;
+import static com.flurgle.camerakit.CameraKit.Constants.METHOD_STANDARD;
+import static com.flurgle.camerakit.CameraKit.Constants.METHOD_STILL;
@Retention(RetentionPolicy.SOURCE)
-@IntDef({CAPTURE_MODE_STANDARD, CAPTURE_MODE_STILL})
+@IntDef({METHOD_STANDARD, METHOD_STILL})
public @interface Method {
}
diff --git a/camerakit/src/main/types/com/flurgle/camerakit/Zoom.java b/camerakit/src/main/types/com/flurgle/camerakit/Zoom.java
index 5bb16513..57f77116 100644
--- a/camerakit/src/main/types/com/flurgle/camerakit/Zoom.java
+++ b/camerakit/src/main/types/com/flurgle/camerakit/Zoom.java
@@ -1,8 +1,14 @@
package com.flurgle.camerakit;
-/**
- * Created by dylanmcintyre on 2/21/17.
- */
+import android.support.annotation.IntDef;
-public class Zoom {
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import static com.flurgle.camerakit.CameraKit.Constants.ZOOM_OFF;
+import static com.flurgle.camerakit.CameraKit.Constants.ZOOM_PINCH;
+
+@Retention(RetentionPolicy.SOURCE)
+@IntDef({ZOOM_OFF, ZOOM_PINCH})
+public @interface Zoom {
}
diff --git a/demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java b/demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
index 0dabfaf8..59d1cc3c 100644
--- a/demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
+++ b/demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
@@ -136,7 +136,7 @@ public class MainActivity extends AppCompatActivity {
startActivity(intent);
}
});
- camera.capturePicture();
+ camera.captureImage();
}
@OnClick(R.id.captureVideo)
@@ -191,10 +191,10 @@ public class MainActivity extends AppCompatActivity {
RadioGroup.OnCheckedChangeListener captureModeChangedListener = new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
- camera.setCaptureMode(
+ camera.setMethod(
checkedId == R.id.modeCaptureQuality ?
- CameraKit.Constants.CAPTURE_MODE_STANDARD :
- CameraKit.Constants.CAPTURE_MODE_STILL
+ CameraKit.Constants.METHOD_STANDARD :
+ CameraKit.Constants.METHOD_STILL
);
Toast.makeText(MainActivity.this, "Picture capture set to" + (checkedId == R.id.modeCaptureQuality ? " quality!" : " speed!"), Toast.LENGTH_SHORT).show();
@@ -215,12 +215,12 @@ public class MainActivity extends AppCompatActivity {
RadioGroup.OnCheckedChangeListener tapToFocusModeChangedListener = new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
- camera.setTapToFocus(
+ camera.setFocus(
checkedId == R.id.modeTapToFocusVisible ?
- CameraKit.Constants.TAP_TO_FOCUS_VISIBLE :
+ CameraKit.Constants.FOCUS_CONTINUOUS :
checkedId == R.id.modeTapToFocusInvisible ?
- CameraKit.Constants.TAP_TO_FOCUS_INVISIBLE :
- CameraKit.Constants.TAP_TO_FOCUS_OFF
+ CameraKit.Constants.FOCUS_TAP :
+ CameraKit.Constants.FOCUS_OFF
);
Toast.makeText(MainActivity.this, "Tap to focus is" + (checkedId == R.id.modeTapToFocusOff ? " off!" : (checkedId == R.id.modeTapToFocusVisible) ? " on and visible!" : " on and invisible!"), Toast.LENGTH_SHORT).show();
diff --git a/demo/src/main/res/layout/activity_main.xml b/demo/src/main/res/layout/activity_main.xml
index 6643a168..bb4e82c7 100644
--- a/demo/src/main/res/layout/activity_main.xml
+++ b/demo/src/main/res/layout/activity_main.xml
@@ -19,11 +19,11 @@
android:layout_height="500dp"
android:layout_gravity="center_horizontal"
app:ckCaptureMode="standard"
- app:ckContinuousFocus="true"
app:ckCropOutput="false"
app:ckFacing="back"
app:ckFlash="off"
- app:ckTapToFocus="visible" />
+ app:ckFocus="continuous"
+ app:ckJpegQuality="100" />