diff --git a/README.md b/README.md
index 01982535..fd84dafb 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@ Try out all the unique features using the CameraKit Demo from the Google Play st
+
## Table of Contents
@@ -19,7 +20,7 @@ Try out all the unique features using the CameraKit Demo from the Google Play st
- [`ckCropOutput`](#ckcropoutput)
- [`ckFacing`](#ckfacing)
- [`ckFlash`](#ckflash)
- - [`ckPictureMode`](#ckpicturemode)
+ - [`ckCaptureMode`](#ckcapturemode)
- [`ckTapToFocus`](#cktaptofocus)
- [`ckAutoFocus`](#ckautofocus)
- [`ckCaptureSize`](#ckcapturesize)
@@ -125,7 +126,7 @@ camera.setCameraListener(new CameraListener() {
camerakit:ckCropOutput="true"
camerakit:ckFacing="back"
camerakit:ckFlash="off"
- camerakit:ckPictureMode="quality"
+ camerakit:ckCaptureMode="quality"
camerakit:ckTapToFocus="on"
camerakit:ckAutoFocus="true"
camerakit:ckCaptureSize="8" />
@@ -154,13 +155,13 @@ camera.setCameraListener(new CameraListener() {
| `on` | Default `CameraView` flash to on. |
| `auto` | Default `CameraView` flash to automatic. |
-#### `ckPictureMode`
+#### `ckCaptureMode`
| Value | Description |
| --------------| -------------|
-| `quality` | Use normal Android Camera API image capturing. |
-| `speed` | Freeze the `CameraView` preview and grab a `Bitmap` of the frame. |
-| `auto` | Default picture mode to `quality`, but fallback to `speed` if capturing is determined to be too slow. |
+| `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. |
#### `ckTapToFocus`
diff --git a/camerakit/build.gradle b/camerakit/build.gradle
index 9b89961e..8f29dda8 100644
--- a/camerakit/build.gradle
+++ b/camerakit/build.gradle
@@ -22,6 +22,13 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
+ sourceSets {
+ main.java.srcDirs += 'src/main/base'
+ main.java.srcDirs += 'src/main/api16'
+ main.java.srcDirs += 'src/main/api21'
+ main.java.srcDirs += 'src/main/types'
+ main.java.srcDirs += 'src/main/utils'
+ }
}
dependencies {
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/Camera1.java b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
similarity index 95%
rename from camerakit/src/main/java/com/flurgle/camerakit/Camera1.java
rename to camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
index c414b9ff..6cb948cc 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/Camera1.java
+++ b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
@@ -9,10 +9,6 @@ import android.support.annotation.NonNull;
import android.support.v4.util.SparseArrayCompat;
import android.view.SurfaceHolder;
-import com.flurgle.camerakit.utils.AspectRatio;
-import com.flurgle.camerakit.utils.Size;
-import com.flurgle.camerakit.utils.YuvUtils;
-
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
@@ -23,6 +19,7 @@ import java.util.TreeSet;
public class Camera1 extends CameraImpl {
private static final SparseArrayCompat FLASH_MODES = new SparseArrayCompat<>();
+
static {
FLASH_MODES.put(CameraKit.Constants.FLASH_OFF, Camera.Parameters.FLASH_MODE_OFF);
FLASH_MODES.put(CameraKit.Constants.FLASH_ON, Camera.Parameters.FLASH_MODE_ON);
@@ -30,6 +27,7 @@ public class Camera1 extends CameraImpl {
}
private static final SparseArrayCompat FACING_MODES = new SparseArrayCompat<>();
+
static {
FACING_MODES.put(CameraKit.Constants.FACING_BACK, Camera.CameraInfo.CAMERA_FACING_BACK);
FACING_MODES.put(CameraKit.Constants.FACING_FRONT, Camera.CameraInfo.CAMERA_FACING_FRONT);
@@ -59,11 +57,11 @@ public class Camera1 extends CameraImpl {
Camera1(@NonNull CameraListener cameraListener, @NonNull PreviewImpl preview) {
super(cameraListener, preview);
-
+
this.mCameraListener = cameraListener;
this.mPreviewSizes = new TreeSet<>();
this.mCaptureSizes = new TreeSet<>();
- this.mVideoFile = new File(getView().getContext().getExternalFilesDir(null), "video.mp4");
+ this.mVideoFile = new File(mPreview.getView().getContext().getExternalFilesDir(null), "video.mp4");
preview.setCallback(new PreviewImpl.Callback() {
@Override
@@ -194,20 +192,11 @@ public class Camera1 extends CameraImpl {
}
@Override
- boolean getAutoFocus() {
- if (!isCameraOpened()) {
- return mAutoFocus;
- }
- String focusMode = mCameraParameters.getFocusMode();
- return focusMode != null && focusMode.contains("continuous");
- }
-
- @Override
- void capturePicture() {
+ void captureStandard() {
if (!isCameraOpened()) {
throw new IllegalStateException("Camera is not ready. Call start() before takePicture().");
}
- if (getAutoFocus()) {
+ if (mAutoFocus) {
mCamera.cancelAutoFocus();
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
@@ -238,7 +227,7 @@ public class Camera1 extends CameraImpl {
new Thread(new ProcessStillTask(data, camera, mCameraInfo, new ProcessStillTask.OnStillProcessedListener() {
@Override
public void onStillProcessed(final YuvImage yuv) {
- getView().post(new Runnable() {
+ mPreview.getView().post(new Runnable() {
@Override
public void run() {
mCameraListener.onPictureTaken(yuv);
@@ -493,12 +482,12 @@ public class Camera1 extends CameraImpl {
}
@Override
- Size getCaptureSize() {
+ Size getCaptureResolution() {
return mCaptureSize;
}
@Override
- Size getPreviewSize() {
+ Size getPreviewResolution() {
return mPreviewSize;
}
}
diff --git a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java
new file mode 100644
index 00000000..69fb49cf
--- /dev/null
+++ b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java
@@ -0,0 +1,493 @@
+package com.flurgle.camerakit;
+
+import android.graphics.YuvImage;
+import android.hardware.Camera;
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder;
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.support.v4.util.SparseArrayCompat;
+import android.view.SurfaceHolder;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+public class Camera2 extends CameraImpl {
+
+ private static final SparseArrayCompat FLASH_MODES = new SparseArrayCompat<>();
+
+ static {
+ FLASH_MODES.put(CameraKit.Constants.FLASH_OFF, Camera.Parameters.FLASH_MODE_OFF);
+ FLASH_MODES.put(CameraKit.Constants.FLASH_ON, Camera.Parameters.FLASH_MODE_ON);
+ FLASH_MODES.put(CameraKit.Constants.FLASH_AUTO, Camera.Parameters.FLASH_MODE_AUTO);
+ }
+
+ private static final SparseArrayCompat FACING_MODES = new SparseArrayCompat<>();
+
+ static {
+ FACING_MODES.put(CameraKit.Constants.FACING_BACK, Camera.CameraInfo.CAMERA_FACING_BACK);
+ FACING_MODES.put(CameraKit.Constants.FACING_FRONT, Camera.CameraInfo.CAMERA_FACING_FRONT);
+ }
+
+ private File mVideoFile;
+
+ private int mCameraId;
+ private Camera mCamera;
+ private Camera.Parameters mCameraParameters;
+ private final Camera.CameraInfo mCameraInfo = new Camera.CameraInfo();
+ private Size mPreviewSize;
+ private Size mCaptureSize;
+
+ private boolean mShowingPreview;
+ private boolean mAutoFocus;
+ private int mFacing;
+ private int mFlash;
+ private int mDisplayOrientation;
+
+ private TreeSet mPreviewSizes;
+ private TreeSet mCaptureSizes;
+
+ private MediaRecorder mMediaRecorder;
+
+ private CameraListener mCameraListener;
+
+ Camera2(@NonNull CameraListener cameraListener, @NonNull PreviewImpl preview) {
+ super(cameraListener, preview);
+
+ this.mCameraListener = cameraListener;
+ this.mPreviewSizes = new TreeSet<>();
+ this.mCaptureSizes = new TreeSet<>();
+ this.mVideoFile = new File(mPreview.getView().getContext().getExternalFilesDir(null), "video.mp4");
+
+ preview.setCallback(new PreviewImpl.Callback() {
+ @Override
+ public void onSurfaceChanged() {
+ if (mCamera != null) {
+ setUpPreview();
+ adjustCameraParameters();
+ }
+ }
+ });
+ }
+
+ @Override
+ void start() {
+ setFacingInternal(mFacing);
+ openCamera();
+ if (mPreview.isReady()) {
+ setUpPreview();
+ }
+ mShowingPreview = true;
+ mCamera.startPreview();
+ }
+
+ @Override
+ void stop() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ }
+ mShowingPreview = false;
+ releaseCamera();
+ }
+
+ @Override
+ boolean isCameraOpened() {
+ return mCamera != null;
+ }
+
+ @Override
+ void setFacing(int facing) {
+ if (mFacing == facing) {
+ return;
+ }
+ if (setFacingInternal(facing) && isCameraOpened()) {
+ stop();
+ start();
+ }
+ }
+
+ private boolean setFacingInternal(int facing) {
+ int trueValue = FACING_MODES.get(facing, -1);
+ if (trueValue == -1) {
+ return false;
+ }
+
+ for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) {
+ Camera.getCameraInfo(i, mCameraInfo);
+ if (mCameraInfo.facing == trueValue) {
+ mCameraId = i;
+ mFacing = facing;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ void setFlash(int flash) {
+ if (flash == mFlash) {
+ return;
+ }
+ if (setFlashInternal(flash)) {
+ mCamera.setParameters(mCameraParameters);
+ }
+ }
+
+ private boolean setFlashInternal(int flash) {
+ if (isCameraOpened()) {
+ List modes = mCameraParameters.getSupportedFlashModes();
+ String mode = FLASH_MODES.get(flash);
+ if (modes != null && modes.contains(mode)) {
+ mCameraParameters.setFlashMode(mode);
+ mFlash = flash;
+ return true;
+ }
+ String currentMode = FLASH_MODES.get(mFlash);
+ if (modes == null || !modes.contains(currentMode)) {
+ mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
+ mFlash = CameraKit.Constants.FLASH_OFF;
+ return true;
+ }
+ return false;
+ } else {
+ mFlash = flash;
+ return false;
+ }
+ }
+
+ @Override
+ void setAutoFocus(boolean autoFocus) {
+ if (autoFocus == mAutoFocus) {
+ return;
+ }
+ if (setAutoFocusInternal(autoFocus)) {
+ mCamera.setParameters(mCameraParameters);
+ }
+ }
+
+ private boolean setAutoFocusInternal(boolean autoFocus) {
+ mAutoFocus = autoFocus;
+ if (isCameraOpened()) {
+ final List modes = mCameraParameters.getSupportedFocusModes();
+ if (autoFocus && 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));
+ }
+
+ mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ void captureStandard() {
+ if (!isCameraOpened()) {
+ throw new IllegalStateException("Camera is not ready. Call start() before takePicture().");
+ }
+ if (mAutoFocus) {
+ mCamera.cancelAutoFocus();
+ mCamera.autoFocus(new Camera.AutoFocusCallback() {
+ @Override
+ public void onAutoFocus(boolean success, Camera camera) {
+ takePictureInternal();
+ }
+ });
+ } else {
+ takePictureInternal();
+ }
+ }
+
+ void takePictureInternal() {
+ mCamera.takePicture(null, null, null, new Camera.PictureCallback() {
+ @Override
+ public void onPictureTaken(byte[] data, Camera camera) {
+ mCameraListener.onPictureTaken(data);
+ camera.startPreview();
+ }
+ });
+ }
+
+ @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() {
+ @Override
+ public void onStillProcessed(final YuvImage yuv) {
+ mPreview.getView().post(new Runnable() {
+ @Override
+ public void run() {
+ mCameraListener.onPictureTaken(yuv);
+ }
+ });
+ }
+ })).start();
+ }
+ });
+ }
+
+ static class ProcessStillTask implements Runnable {
+
+ byte[] data;
+ Camera camera;
+ Camera.CameraInfo cameraInfo;
+ OnStillProcessedListener onStillProcessedListener;
+
+ public ProcessStillTask(byte[] data, Camera camera, Camera.CameraInfo cameraInfo, OnStillProcessedListener onStillProcessedListener) {
+ this.data = data;
+ this.camera = camera;
+ this.cameraInfo = cameraInfo;
+ this.onStillProcessedListener = onStillProcessedListener;
+ }
+
+ @Override
+ public void run() {
+ Camera.Parameters parameters = camera.getParameters();
+ int width = parameters.getPreviewSize().width;
+ int height = parameters.getPreviewSize().height;
+ int rotation = cameraInfo.orientation;
+ byte[] rotatedData = YuvUtils.rotateNV21(data, width, height, rotation);
+
+ int postWidth;
+ int postHeight;
+
+ switch (rotation) {
+ case 90:
+ case 270:
+ postWidth = height;
+ postHeight = width;
+ break;
+
+ case 0:
+ case 180:
+ default:
+ postWidth = width;
+ postHeight = height;
+ break;
+ }
+
+ YuvImage yuv = new YuvImage(rotatedData, parameters.getPreviewFormat(), postWidth, postHeight, null);
+
+ onStillProcessedListener.onStillProcessed(yuv);
+ }
+
+ interface OnStillProcessedListener {
+ void onStillProcessed(YuvImage yuv);
+ }
+
+ }
+
+ @Override
+ void startVideo() {
+ try {
+ prepareMediaRecorder();
+ } catch (IOException e) {
+ if (mMediaRecorder != null) {
+ mMediaRecorder.release();
+ }
+
+ return;
+ }
+ }
+
+ void prepareMediaRecorder() throws IOException {
+ mCamera.unlock();
+
+ mMediaRecorder = new MediaRecorder();
+ mMediaRecorder.setCamera(mCamera);
+
+ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+ mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));
+
+ mMediaRecorder.setOutputFile(mVideoFile.getAbsolutePath());
+ mMediaRecorder.setOrientationHint(mCameraInfo.orientation);
+
+ mMediaRecorder.prepare();
+ mMediaRecorder.start();
+ }
+
+ @Override
+ void endVideo() {
+ if (mMediaRecorder != null) {
+ mMediaRecorder.stop();
+ mMediaRecorder = null;
+ }
+
+ mCameraListener.onVideoTaken(mVideoFile);
+
+ }
+
+ @Override
+ void focus() {
+ mCamera.autoFocus(null);
+ }
+
+ @Override
+ void setDisplayOrientation(int displayOrientation) {
+ if (mDisplayOrientation == displayOrientation) {
+ return;
+ }
+ mDisplayOrientation = displayOrientation;
+ if (isCameraOpened()) {
+ int cameraRotation = calcCameraRotation(displayOrientation);
+ mCameraParameters.setRotation(cameraRotation);
+ mCamera.setParameters(mCameraParameters);
+ final boolean needsToStopPreview = mShowingPreview && Build.VERSION.SDK_INT < 14;
+ if (needsToStopPreview) {
+ mCamera.stopPreview();
+ }
+ mCamera.setDisplayOrientation(cameraRotation);
+ if (needsToStopPreview) {
+ mCamera.startPreview();
+ }
+ }
+ }
+
+ private int calcCameraRotation(int rotation) {
+ if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+ return (360 - (mCameraInfo.orientation + rotation) % 360) % 360;
+ } else {
+ return (mCameraInfo.orientation - rotation + 360) % 360;
+ }
+ }
+
+ private void setUpPreview() {
+ try {
+ if (mPreview.getOutputClass() == SurfaceHolder.class) {
+ final boolean needsToStopPreview = mShowingPreview && Build.VERSION.SDK_INT < 14;
+ if (needsToStopPreview) {
+ mCamera.stopPreview();
+ }
+ mCamera.setPreviewDisplay(mPreview.getSurfaceHolder());
+ if (needsToStopPreview) {
+ mCamera.startPreview();
+ }
+ } else {
+ mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void adjustCameraParameters() {
+ SortedSet sizes = mPreviewSizes;
+ mPreviewSize = chooseOptimalSize(sizes);
+ final Camera.Size currentSize = mCameraParameters.getPictureSize();
+ if (currentSize.width != mPreviewSize.getWidth() || currentSize.height != mPreviewSize.getHeight()) {
+ Iterator iterator = mCaptureSizes.descendingIterator();
+ Size pictureSize;
+ while ((pictureSize = iterator.next()) != null) {
+ if (AspectRatio.of(mPreviewSize.getWidth(), mPreviewSize.getHeight()).matches(pictureSize)) {
+ break;
+ }
+ }
+
+ if (pictureSize == null) {
+ pictureSize = mCaptureSizes.last();
+ }
+
+ mCaptureSize = pictureSize;
+
+ if (mShowingPreview) {
+ mCamera.stopPreview();
+ }
+
+ mCameraParameters.setPreviewSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
+ mPreview.setTruePreviewSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
+ mCameraParameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight());
+ mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation) + (mFacing == CameraKit.Constants.FACING_FRONT ? 180 : 0));
+
+ setAutoFocusInternal(mAutoFocus);
+
+ //setFlashInternal(mFlash);
+
+ mCamera.setParameters(mCameraParameters);
+ if (mShowingPreview) {
+ mCamera.startPreview();
+ }
+ }
+ }
+
+ private Size chooseOptimalSize(SortedSet sizes) {
+ if (!mPreview.isReady()) { // Not yet laid out
+ return sizes.last(); // Return the smallest size
+ }
+
+ int desiredWidth;
+ int desiredHeight;
+ final int surfaceWidth = mPreview.getWidth();
+ final int surfaceHeight = mPreview.getHeight();
+ if (mDisplayOrientation == 90 || mDisplayOrientation == 270) {
+ desiredWidth = surfaceHeight;
+ desiredHeight = surfaceWidth;
+ } else {
+ desiredWidth = surfaceWidth;
+ desiredHeight = surfaceHeight;
+ }
+ Size result = null;
+ for (Size size : sizes) { // Iterate from small to large
+ if (desiredWidth <= size.getWidth() && desiredHeight <= size.getHeight()) {
+ return size;
+
+ }
+ result = size;
+ }
+ return result;
+ }
+
+ private void openCamera() {
+ if (mCamera != null) {
+ releaseCamera();
+ }
+ mCamera = Camera.open(mCameraId);
+ mCameraParameters = mCamera.getParameters();
+ // Supported preview sizes
+ mPreviewSizes.clear();
+ for (Camera.Size size : mCameraParameters.getSupportedPreviewSizes()) {
+ mPreviewSizes.add(new Size(size.width, size.height));
+ }
+ // Supported picture sizes;
+ mCaptureSizes.clear();
+ for (Camera.Size size : mCameraParameters.getSupportedPictureSizes()) {
+ mCaptureSizes.add(new Size(size.width, size.height));
+ }
+
+ adjustCameraParameters();
+ mCamera.setDisplayOrientation(calcCameraRotation(mDisplayOrientation));
+
+ mCameraListener.onCameraOpened();
+ }
+
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.release();
+ mCamera = null;
+ mCameraListener.onCameraClosed();
+ }
+ }
+
+ @Override
+ Size getCaptureResolution() {
+ return mCaptureSize;
+ }
+
+ @Override
+ Size getPreviewResolution() {
+ return mPreviewSize;
+ }
+}
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraImpl.java b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
similarity index 66%
rename from camerakit/src/main/java/com/flurgle/camerakit/CameraImpl.java
rename to camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
index 1ee663cd..df04432d 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/CameraImpl.java
+++ b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
@@ -1,11 +1,5 @@
package com.flurgle.camerakit;
-import android.view.View;
-
-import com.flurgle.camerakit.types.Facing;
-import com.flurgle.camerakit.types.Flash;
-import com.flurgle.camerakit.utils.Size;
-
public abstract class CameraImpl {
protected CameraListener mCameraListener;
@@ -16,38 +10,25 @@ public abstract class CameraImpl {
mPreview = preview;
}
- View getView() {
- return mPreview.getView();
- }
-
abstract void start();
-
abstract void stop();
abstract boolean isCameraOpened();
abstract void setFacing(@Facing int facing);
-
abstract void setFlash(@Flash int flash);
-
abstract void setAutoFocus(boolean autoFocus);
- abstract boolean getAutoFocus();
-
- abstract void capturePicture();
+ abstract void setDisplayOrientation(int displayOrientation);
+ abstract void focus();
+ abstract void captureStandard();
abstract void captureStill();
abstract void startVideo();
-
abstract void endVideo();
- abstract void focus();
-
- abstract void setDisplayOrientation(int displayOrientation);
-
- abstract Size getCaptureSize();
-
- abstract Size getPreviewSize();
+ abstract Size getCaptureResolution();
+ abstract Size getPreviewResolution();
}
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/PreviewImpl.java b/camerakit/src/main/base/com/flurgle/camerakit/PreviewImpl.java
similarity index 97%
rename from camerakit/src/main/java/com/flurgle/camerakit/PreviewImpl.java
rename to camerakit/src/main/base/com/flurgle/camerakit/PreviewImpl.java
index 67902178..3850416f 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/PreviewImpl.java
+++ b/camerakit/src/main/base/com/flurgle/camerakit/PreviewImpl.java
@@ -5,8 +5,6 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
-import com.flurgle.camerakit.utils.AspectRatio;
-
public abstract class PreviewImpl {
interface Callback {
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/TextureViewPreview.java b/camerakit/src/main/base/com/flurgle/camerakit/TextureViewPreview.java
similarity index 100%
rename from camerakit/src/main/java/com/flurgle/camerakit/TextureViewPreview.java
rename to camerakit/src/main/base/com/flurgle/camerakit/TextureViewPreview.java
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
index aa805f59..16b30b92 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
+++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
@@ -11,8 +11,8 @@ public class CameraKit {
public static final int FLASH_ON = 1;
public static final int FLASH_AUTO = 2;
- public static final int PICTURE_MODE_QUALITY = 0;
- public static final int PICTURE_MODE_SPEED = 1;
+ 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 TAP_TO_FOCUS_VISIBLE = 0;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
index 34f6446f..7cfc6e53 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
+++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
@@ -24,15 +24,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
-import com.flurgle.camerakit.types.Facing;
-import com.flurgle.camerakit.types.Flash;
-import com.flurgle.camerakit.types.PictureMode;
-import com.flurgle.camerakit.types.TapToFocus;
-import com.flurgle.camerakit.utils.AspectRatio;
-import com.flurgle.camerakit.utils.CenterCrop;
-import com.flurgle.camerakit.utils.DisplayOrientationDetector;
-import com.flurgle.camerakit.utils.Size;
-
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -41,14 +32,15 @@ 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.PICTURE_MODE_QUALITY;
-import static com.flurgle.camerakit.CameraKit.Constants.PICTURE_MODE_SPEED;
+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.TAP_TO_FOCUS_VISIBLE;
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;
@@ -56,18 +48,20 @@ public class CameraView extends FrameLayout {
@Flash
private int mFlash;
- @PictureMode
- private int mPictureMode;
-
- private boolean mCropOutput;
-
@TapToFocus
private int mTapToFocus;
+ @CaptureMode
+ private int mCaptureMode;
+
+ private boolean mCropOutput;
+
private boolean mAutoFocus;
private float mCaptureSize;
+ private int mJpegCompression;
+
private boolean mAdjustViewBounds;
private boolean mWaitingForPermission;
@@ -100,18 +94,18 @@ public class CameraView extends FrameLayout {
mFlash = a.getInteger(R.styleable.CameraView_ckFlash, FLASH_OFF);
}
- if (attr == R.styleable.CameraView_ckPictureMode) {
- mPictureMode = a.getInteger(R.styleable.CameraView_ckPictureMode, PICTURE_MODE_QUALITY);
+ if (attr == R.styleable.CameraView_ckTapToFocus) {
+ mTapToFocus = a.getInteger(R.styleable.CameraView_ckTapToFocus, TAP_TO_FOCUS_VISIBLE);
+ }
+
+ if (attr == R.styleable.CameraView_ckCaptureMode) {
+ mCaptureMode = a.getInteger(R.styleable.CameraView_ckCaptureMode, CAPTURE_MODE_STANDARD);
}
if (attr == R.styleable.CameraView_ckCropOutput) {
mCropOutput = a.getBoolean(R.styleable.CameraView_ckCropOutput, false);
}
- if (attr == R.styleable.CameraView_ckTapToFocus) {
- mTapToFocus = a.getInteger(R.styleable.CameraView_ckTapToFocus, TAP_TO_FOCUS_VISIBLE);
- }
-
if (attr == R.styleable.CameraView_ckAutoFocus) {
mAutoFocus = a.getBoolean(R.styleable.CameraView_ckAutoFocus, true);
}
@@ -120,6 +114,10 @@ public class CameraView extends FrameLayout {
mCaptureSize = a.getFloat(R.styleable.CameraView_ckCaptureSize, DEFAULT_CAPTURE_SIZE);
}
+ if (attr == R.styleable.CameraView_ckJpegCompression) {
+ mJpegCompression = a.getInteger(R.styleable.CameraView_ckJpegCompression, DEFAULT_JPEG_COMPRESSION);
+ }
+
if (attr == R.styleable.CameraView_android_adjustViewBounds) {
mAdjustViewBounds = a.getBoolean(R.styleable.CameraView_android_adjustViewBounds, false);
}
@@ -134,7 +132,7 @@ public class CameraView extends FrameLayout {
setFacing(mFacing);
setFlash(mFlash);
- setPictureMode(mPictureMode);
+ setPictureMode(mCaptureMode);
setCropOutput(mCropOutput);
setTapToFocus(mTapToFocus);
setAutoFocus(mAutoFocus);
@@ -243,13 +241,13 @@ public class CameraView extends FrameLayout {
return mFlash;
}
- public void setPictureMode(@PictureMode int pictureMode) {
- this.mPictureMode = pictureMode;
+ public void setPictureMode(@CaptureMode int pictureMode) {
+ this.mCaptureMode = pictureMode;
}
- @PictureMode
+ @CaptureMode
public int getPictureMode() {
- return mPictureMode;
+ return mCaptureMode;
}
public void setCropOutput(boolean cropOutput) {
@@ -278,11 +276,11 @@ public class CameraView extends FrameLayout {
}
public void capturePicture() {
- switch (mPictureMode) {
- case PICTURE_MODE_QUALITY:
- mCameraImpl.capturePicture();
+ switch (mCaptureMode) {
+ case CAPTURE_MODE_STANDARD:
+ mCameraImpl.captureStandard();
break;
- case PICTURE_MODE_SPEED:
+ case CAPTURE_MODE_STILL:
mCameraImpl.captureStill();
break;
}
@@ -297,11 +295,11 @@ public class CameraView extends FrameLayout {
}
public Size getPreviewSize() {
- return mCameraImpl != null ? mCameraImpl.getPreviewSize() : null;
+ return mCameraImpl != null ? mCameraImpl.getPreviewResolution() : null;
}
public Size getCaptureSize() {
- return mCameraImpl != null ? mCameraImpl.getCaptureSize() : null;
+ return mCameraImpl != null ? mCameraImpl.getCaptureResolution() : null;
}
private void requestCameraPermission() {
@@ -405,10 +403,10 @@ public class CameraView extends FrameLayout {
public void onPictureTaken(byte[] jpeg) {
super.onPictureTaken(jpeg);
if (mCropOutput) {
- int width = mPictureMode == PICTURE_MODE_QUALITY ? mCameraImpl.getCaptureSize().getWidth() : mCameraImpl.getPreviewSize().getWidth();
- int height = mPictureMode == PICTURE_MODE_QUALITY ? mCameraImpl.getCaptureSize().getHeight() : mCameraImpl.getPreviewSize().getHeight();
+ int width = mCaptureMode == CAPTURE_MODE_STANDARD ? mCameraImpl.getCaptureResolution().getWidth() : mCameraImpl.getPreviewResolution().getWidth();
+ int height = mCaptureMode == CAPTURE_MODE_STANDARD ? mCameraImpl.getCaptureResolution().getHeight() : mCameraImpl.getPreviewResolution().getHeight();
AspectRatio outputRatio = AspectRatio.of(getWidth(), getHeight());
- getCameraListener().onPictureTaken(new CenterCrop(jpeg, outputRatio).getJpeg());
+ getCameraListener().onPictureTaken(new CenterCrop(jpeg, outputRatio, mJpegCompression).getJpeg());
} else {
getCameraListener().onPictureTaken(jpeg);
}
@@ -419,10 +417,10 @@ public class CameraView extends FrameLayout {
super.onPictureTaken(yuv);
if (mCropOutput) {
AspectRatio outputRatio = AspectRatio.of(getWidth(), getHeight());
- getCameraListener().onPictureTaken(new CenterCrop(yuv, outputRatio).getJpeg());
+ getCameraListener().onPictureTaken(new CenterCrop(yuv, outputRatio, mJpegCompression).getJpeg());
} else {
ByteArrayOutputStream out = new ByteArrayOutputStream();
- yuv.compressToJpeg(new Rect(0, 0, yuv.getWidth(), yuv.getHeight()), 50, out);
+ yuv.compressToJpeg(new Rect(0, 0, yuv.getWidth(), yuv.getHeight()), mJpegCompression, out);
getCameraListener().onPictureTaken(out.toByteArray());
}
}
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/types/PictureMode.java b/camerakit/src/main/java/com/flurgle/camerakit/types/PictureMode.java
deleted file mode 100644
index 7317e096..00000000
--- a/camerakit/src/main/java/com/flurgle/camerakit/types/PictureMode.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.flurgle.camerakit.types;
-
-import android.support.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-import static com.flurgle.camerakit.CameraKit.Constants.PICTURE_MODE_QUALITY;
-import static com.flurgle.camerakit.CameraKit.Constants.PICTURE_MODE_SPEED;
-
-@Retention(RetentionPolicy.SOURCE)
-@IntDef({PICTURE_MODE_QUALITY, PICTURE_MODE_SPEED})
-public @interface PictureMode {
-}
diff --git a/camerakit/src/main/res/values/attrs.xml b/camerakit/src/main/res/values/attrs.xml
index 62d49bce..62ab920e 100644
--- a/camerakit/src/main/res/values/attrs.xml
+++ b/camerakit/src/main/res/values/attrs.xml
@@ -14,9 +14,9 @@
-
-
-
+
+
+
@@ -32,6 +32,8 @@
+
+
diff --git a/camerakit/src/main/types/com/flurgle/camerakit/CaptureMode.java b/camerakit/src/main/types/com/flurgle/camerakit/CaptureMode.java
new file mode 100644
index 00000000..a6e923c2
--- /dev/null
+++ b/camerakit/src/main/types/com/flurgle/camerakit/CaptureMode.java
@@ -0,0 +1,14 @@
+package com.flurgle.camerakit;
+
+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;
+
+@Retention(RetentionPolicy.SOURCE)
+@IntDef({CAPTURE_MODE_STANDARD, CAPTURE_MODE_STILL})
+public @interface CaptureMode {
+}
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/types/Facing.java b/camerakit/src/main/types/com/flurgle/camerakit/Facing.java
similarity index 90%
rename from camerakit/src/main/java/com/flurgle/camerakit/types/Facing.java
rename to camerakit/src/main/types/com/flurgle/camerakit/Facing.java
index 690f9536..15a555f7 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/types/Facing.java
+++ b/camerakit/src/main/types/com/flurgle/camerakit/Facing.java
@@ -1,4 +1,4 @@
-package com.flurgle.camerakit.types;
+package com.flurgle.camerakit;
import android.support.annotation.IntDef;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/types/Flash.java b/camerakit/src/main/types/com/flurgle/camerakit/Flash.java
similarity index 91%
rename from camerakit/src/main/java/com/flurgle/camerakit/types/Flash.java
rename to camerakit/src/main/types/com/flurgle/camerakit/Flash.java
index a65dee85..08055486 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/types/Flash.java
+++ b/camerakit/src/main/types/com/flurgle/camerakit/Flash.java
@@ -1,4 +1,4 @@
-package com.flurgle.camerakit.types;
+package com.flurgle.camerakit;
import android.support.annotation.IntDef;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/types/TapToFocus.java b/camerakit/src/main/types/com/flurgle/camerakit/TapToFocus.java
similarity index 92%
rename from camerakit/src/main/java/com/flurgle/camerakit/types/TapToFocus.java
rename to camerakit/src/main/types/com/flurgle/camerakit/TapToFocus.java
index 10920134..9e6860d4 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/types/TapToFocus.java
+++ b/camerakit/src/main/types/com/flurgle/camerakit/TapToFocus.java
@@ -1,4 +1,4 @@
-package com.flurgle.camerakit.types;
+package com.flurgle.camerakit;
import android.support.annotation.IntDef;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/utils/AspectRatio.java b/camerakit/src/main/utils/com/flurgle/camerakit/AspectRatio.java
similarity index 98%
rename from camerakit/src/main/java/com/flurgle/camerakit/utils/AspectRatio.java
rename to camerakit/src/main/utils/com/flurgle/camerakit/AspectRatio.java
index e425f318..2f153510 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/utils/AspectRatio.java
+++ b/camerakit/src/main/utils/com/flurgle/camerakit/AspectRatio.java
@@ -1,4 +1,4 @@
-package com.flurgle.camerakit.utils;
+package com.flurgle.camerakit;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/utils/CenterCrop.java b/camerakit/src/main/utils/com/flurgle/camerakit/CenterCrop.java
similarity index 91%
rename from camerakit/src/main/java/com/flurgle/camerakit/utils/CenterCrop.java
rename to camerakit/src/main/utils/com/flurgle/camerakit/CenterCrop.java
index e7a88fd3..6b10bf7e 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/utils/CenterCrop.java
+++ b/camerakit/src/main/utils/com/flurgle/camerakit/CenterCrop.java
@@ -1,4 +1,4 @@
-package com.flurgle.camerakit.utils;
+package com.flurgle.camerakit;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -14,14 +14,14 @@ public class CenterCrop {
private byte[] croppedJpeg;
- public CenterCrop(YuvImage yuv, AspectRatio targetRatio) {
+ public CenterCrop(YuvImage yuv, AspectRatio targetRatio, int jpegCompression) {
Rect crop = getCrop(yuv.getWidth(), yuv.getHeight(), targetRatio);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuv.compressToJpeg(crop, 100, out);
this.croppedJpeg = out.toByteArray();
}
- public CenterCrop(byte[] jpeg, AspectRatio targetRatio) {
+ public CenterCrop(byte[] jpeg, AspectRatio targetRatio, int jpegCompression) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length, options);
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/utils/DisplayOrientationDetector.java b/camerakit/src/main/utils/com/flurgle/camerakit/DisplayOrientationDetector.java
similarity index 98%
rename from camerakit/src/main/java/com/flurgle/camerakit/utils/DisplayOrientationDetector.java
rename to camerakit/src/main/utils/com/flurgle/camerakit/DisplayOrientationDetector.java
index e21054ac..28caef8a 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/utils/DisplayOrientationDetector.java
+++ b/camerakit/src/main/utils/com/flurgle/camerakit/DisplayOrientationDetector.java
@@ -1,4 +1,4 @@
-package com.flurgle.camerakit.utils;
+package com.flurgle.camerakit;
import android.content.Context;
import android.util.SparseIntArray;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/utils/Size.java b/camerakit/src/main/utils/com/flurgle/camerakit/Size.java
similarity index 96%
rename from camerakit/src/main/java/com/flurgle/camerakit/utils/Size.java
rename to camerakit/src/main/utils/com/flurgle/camerakit/Size.java
index 1fc108ac..08e54a8f 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/utils/Size.java
+++ b/camerakit/src/main/utils/com/flurgle/camerakit/Size.java
@@ -1,4 +1,4 @@
-package com.flurgle.camerakit.utils;
+package com.flurgle.camerakit;
import android.support.annotation.NonNull;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/utils/YuvUtils.java b/camerakit/src/main/utils/com/flurgle/camerakit/YuvUtils.java
similarity index 96%
rename from camerakit/src/main/java/com/flurgle/camerakit/utils/YuvUtils.java
rename to camerakit/src/main/utils/com/flurgle/camerakit/YuvUtils.java
index ef7251f9..a41d82ab 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/utils/YuvUtils.java
+++ b/camerakit/src/main/utils/com/flurgle/camerakit/YuvUtils.java
@@ -1,6 +1,7 @@
-package com.flurgle.camerakit.utils;
+package com.flurgle.camerakit;
import android.media.Image;
+import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -27,7 +28,7 @@ public class YuvUtils {
outputStream.write(v);
outputStream.write(u);
} catch (IOException e) {
-
+ Log.e("CameraKit", e.toString());
}
return outputStream.toByteArray();
}
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 a586b1e7..3aabf61d 100644
--- a/demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
+++ b/demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
@@ -193,8 +193,8 @@ public class MainActivity extends AppCompatActivity {
public void onCheckedChanged(RadioGroup group, int checkedId) {
camera.setPictureMode(
checkedId == R.id.modeCaptureQuality ?
- CameraKit.Constants.PICTURE_MODE_QUALITY :
- CameraKit.Constants.PICTURE_MODE_SPEED
+ CameraKit.Constants.CAPTURE_MODE_STANDARD :
+ CameraKit.Constants.CAPTURE_MODE_STILL
);
Toast.makeText(MainActivity.this, "Picture capture set to" + (checkedId == R.id.modeCaptureQuality ? " quality!" : " speed!"), Toast.LENGTH_SHORT).show();
diff --git a/demo/src/main/java/com/flurgle/camerakit/demo/PreviewActivity.java b/demo/src/main/java/com/flurgle/camerakit/demo/PreviewActivity.java
index f61368d3..996d3741 100644
--- a/demo/src/main/java/com/flurgle/camerakit/demo/PreviewActivity.java
+++ b/demo/src/main/java/com/flurgle/camerakit/demo/PreviewActivity.java
@@ -7,8 +7,8 @@ import android.support.annotation.Nullable;
import android.widget.ImageView;
import android.widget.TextView;
-import com.flurgle.camerakit.utils.AspectRatio;
-import com.flurgle.camerakit.utils.Size;
+import com.flurgle.camerakit.AspectRatio;
+import com.flurgle.camerakit.Size;
import butterknife.BindView;
import butterknife.ButterKnife;
diff --git a/demo/src/main/java/com/flurgle/camerakit/demo/ResultHolder.java b/demo/src/main/java/com/flurgle/camerakit/demo/ResultHolder.java
index 46be0ad9..2679785e 100644
--- a/demo/src/main/java/com/flurgle/camerakit/demo/ResultHolder.java
+++ b/demo/src/main/java/com/flurgle/camerakit/demo/ResultHolder.java
@@ -3,7 +3,7 @@ package com.flurgle.camerakit.demo;
import android.graphics.Bitmap;
import android.support.annotation.Nullable;
-import com.flurgle.camerakit.utils.Size;
+import com.flurgle.camerakit.Size;
import java.lang.ref.WeakReference;
diff --git a/demo/src/main/res/layout/activity_main.xml b/demo/src/main/res/layout/activity_main.xml
index b1822ebf..a48ee39f 100644
--- a/demo/src/main/res/layout/activity_main.xml
+++ b/demo/src/main/res/layout/activity_main.xml
@@ -21,7 +21,7 @@
app:ckCropOutput="false"
app:ckFacing="back"
app:ckFlash="off"
- app:ckPictureMode="quality"
+ app:ckCaptureMode="standard"
app:ckTapToFocus="visible" />