diff --git a/README.md b/README.md
index fafbcaa9..41a58be3 100644
--- a/README.md
+++ b/README.md
@@ -24,9 +24,11 @@ Try out all the unique features using the CameraKit Demo from the Google Play st
- [`ckFacing`](#ckfacing)
- [`ckFlash`](#ckflash)
- [`ckCaptureMode`](#ckcapturemode)
+ - [`ckPinchToZoom`](#ckpinchtozoom)
- [`ckTapToFocus`](#cktaptofocus)
- [`ckAutoFocus`](#ckautofocus)
- [`ckCaptureSize`](#ckcapturesize)
+ - [`ckJpegCompression`](#ckjpegcompression)
- [Capturing Images](#capturing-images)
- [Capturing Video](#capturing-video)
- [Automatic Permissions Behavior](#automatic-permissions-behavior)
@@ -44,15 +46,17 @@ Try out all the unique features using the CameraKit Demo from the Google Play st
## Features
- Image and video capture seamlessly working with the same preview session.
+- Automatic use of both Camera and Camera2 APIs.
- Automatic system permission handling.
- 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_QUALITY`: an image captured normally using the camera APIs.
- - `PICTURE_MODE_SPEED`: a freeze frame of the `CameraView` preview (similar to SnapChat and Instagram) for devices with slower cameras.
+ - `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.
- Automatic picture mode determination based on measured speed.
- Built-in tap to focus and auto focus.
+- Built-in pinch to zoom.
## Setup
@@ -70,7 +74,7 @@ To use CameraKit, simply add a `CameraView` to your layout:
+ android:layout_height="wrap_content" />
```
Make sure you override `onResume` and `onPause` in your activity, and make calls respectively to `CameraView.start()` and `CameraView.stop()`.
@@ -130,9 +134,11 @@ camera.setCameraListener(new CameraListener() {
camerakit:ckFacing="back"
camerakit:ckFlash="off"
camerakit:ckCaptureMode="quality"
+ camerakit:ckPinchToZoom="true"
camerakit:ckTapToFocus="on"
camerakit:ckAutoFocus="true"
- camerakit:ckCaptureSize="8" />
+ camerakit:ckCaptureSize="8"
+ camerakit:ckJpegCompression="100" />
```
#### `ckCropOutput`
@@ -149,7 +155,6 @@ camera.setCameraListener(new CameraListener() {
| `back` | Default `CameraView` preview to back camera. |
| `front` | Default `CameraView` preview to front camera. |
-
#### `ckFlash`
| Value | Description |
@@ -166,6 +171,13 @@ camera.setCameraListener(new CameraListener() {
| `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`
+
+| Value | Description |
+| --------------| -------------|
+| `true` | User can zoom using pinching gestures with their fingers. |
+| `false` | Default pinch to zoom behavior disabled. |
+
#### `ckTapToFocus`
| Value | Description |
@@ -188,6 +200,13 @@ camera.setCameraListener(new CameraListener() {
| `n <= 0` | Capture at the highest quality possible. |
| `n > 0` | Capture at a size of approximately `n` megapixels. |
+#### `ckJpegCompression`
+
+| Value | Description |
+| --------------| -------------|
+| `0 <= n <= 100`| Percent quality for returned JPEG data. |
+
+
### Capturing Images
To capture an image just call `CameraView.capturePicture()`. Make sure you setup a `CameraListener` to handle the image callback.
diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
index 6cb948cc..9e48cc94 100644
--- a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
+++ b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
@@ -2,179 +2,111 @@ 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.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.SortedSet;
+import java.util.Set;
import java.util.TreeSet;
+@SuppressWarnings("deprecation")
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);
- 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 Camera.CameraInfo mCameraInfo;
private Size mPreviewSize;
private Size mCaptureSize;
- private boolean mShowingPreview;
- private boolean mAutoFocus;
private int mFacing;
private int mFlash;
+ private boolean mContinuousFocus;
private int mDisplayOrientation;
- private TreeSet mPreviewSizes;
- private TreeSet mCaptureSizes;
-
- private MediaRecorder mMediaRecorder;
-
- private CameraListener mCameraListener;
-
- 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(mPreview.getView().getContext().getExternalFilesDir(null), "video.mp4");
-
+ Camera1(CameraListener callback, PreviewImpl preview) {
+ super(callback, preview);
preview.setCallback(new PreviewImpl.Callback() {
@Override
public void onSurfaceChanged() {
if (mCamera != null) {
- setUpPreview();
+ setupPreview();
adjustCameraParameters();
}
}
});
+
+ mCameraInfo = new Camera.CameraInfo();
}
+ // CameraImpl:
+
@Override
void start() {
- setFacingInternal(mFacing);
+ setFacing(mFacing);
openCamera();
- if (mPreview.isReady()) {
- setUpPreview();
- }
- mShowingPreview = true;
+ if (mPreview.isReady()) setupPreview();
mCamera.startPreview();
}
@Override
void stop() {
- if (mCamera != null) {
- mCamera.stopPreview();
- }
- mShowingPreview = false;
+ if (mCamera != null) mCamera.stopPreview();
releaseCamera();
}
@Override
- boolean isCameraOpened() {
- return mCamera != null;
- }
-
- @Override
- void setFacing(int facing) {
- if (mFacing == facing) {
+ void setFacing(@Facing int facing) {
+ int internalFacing = new ConstantMapper.Facing(facing).map();
+ if (internalFacing == -1) {
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) {
+ if (mCameraInfo.facing == internalFacing) {
mCameraId = i;
mFacing = facing;
- return true;
+ break;
}
}
- return false;
- }
-
- @Override
- void setFlash(int flash) {
- if (flash == mFlash) {
- return;
- }
- if (setFlashInternal(flash)) {
- mCamera.setParameters(mCameraParameters);
+ if (mFacing == facing && isCameraOpened()) {
+ stop();
+ start();
}
}
- private boolean setFlashInternal(int flash) {
+ @Override
+ void setFlash(@Flash int flash) {
if (isCameraOpened()) {
- List modes = mCameraParameters.getSupportedFlashModes();
- String mode = FLASH_MODES.get(flash);
- if (modes != null && modes.contains(mode)) {
- mCameraParameters.setFlashMode(mode);
+ List flashes = mCameraParameters.getSupportedFlashModes();
+ String internalFlash = new ConstantMapper.Flash(flash).map();
+ if (flashes != null && flashes.contains(internalFlash)) {
+ mCameraParameters.setFlashMode(internalFlash);
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;
+ } else {
+ 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;
+ }
}
- return false;
+
+ mCamera.setParameters(mCameraParameters);
} 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()) {
+ void setContinuousFocus(boolean continuousFocus) {
+ this.mContinuousFocus = continuousFocus;
+ if (mCameraParameters != null) {
final List modes = mCameraParameters.getSupportedFocusModes();
- if (autoFocus && modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
+ 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);
@@ -183,33 +115,26 @@ public class Camera1 extends CameraImpl {
} 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 setDisplayOrientation(int displayOrientation) {
+ this.mDisplayOrientation = displayOrientation;
+ }
+
+ @Override
+ void focus() {
+ mCamera.autoFocus(null);
+ }
+
+ @Override
+ void zoom(float percentZoom) {
+
}
- void takePictureInternal() {
+ @Override
+ void captureStandard() {
mCamera.takePicture(null, null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
@@ -227,155 +152,106 @@ public class Camera1 extends CameraImpl {
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);
- }
- });
+ mCameraListener.onPictureTaken(yuv);
}
})).start();
}
});
}
- static class ProcessStillTask implements Runnable {
+ @Override
+ void startVideo() {
- 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
+ void endVideo() {
- @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;
+ @Override
+ Size getCaptureResolution() {
+ if (mCaptureSize == null && mCameraParameters != null) {
+ TreeSet sizes = new TreeSet<>();
+ for (Camera.Size size : mCameraParameters.getSupportedPictureSizes()) {
+ sizes.add(new Size(size.width, size.height));
}
- YuvImage yuv = new YuvImage(rotatedData, parameters.getPreviewFormat(), postWidth, postHeight, null);
-
- onStillProcessedListener.onStillProcessed(yuv);
- }
-
- interface OnStillProcessedListener {
- void onStillProcessed(YuvImage yuv);
+ TreeSet aspectRatios = findCommonAspectRatios(
+ mCameraParameters.getSupportedPreviewSizes(),
+ mCameraParameters.getSupportedPictureSizes()
+ );
+ AspectRatio targetRatio = aspectRatios.last();
+
+ Iterator descendingSizes = sizes.descendingIterator();
+ Size size;
+ while (descendingSizes.hasNext() && mCaptureSize == null) {
+ size = descendingSizes.next();
+ if (targetRatio.matches(size)) {
+ mCaptureSize = size;
+ break;
+ }
+ }
}
+ return mCaptureSize;
}
@Override
- void startVideo() {
- try {
- prepareMediaRecorder();
- } catch (IOException e) {
- if (mMediaRecorder != null) {
- mMediaRecorder.release();
+ Size getPreviewResolution() {
+ if (mPreviewSize == null && mCameraParameters != null) {
+ TreeSet sizes = new TreeSet<>();
+ for (Camera.Size size : mCameraParameters.getSupportedPreviewSizes()) {
+ sizes.add(new Size(size.width, size.height));
}
- return;
+ TreeSet aspectRatios = findCommonAspectRatios(
+ mCameraParameters.getSupportedPreviewSizes(),
+ mCameraParameters.getSupportedPictureSizes()
+ );
+ AspectRatio targetRatio = aspectRatios.last();
+
+ Iterator descendingSizes = sizes.descendingIterator();
+ Size size;
+ while (descendingSizes.hasNext() && mPreviewSize == null) {
+ size = descendingSizes.next();
+ if (targetRatio.matches(size)) {
+ mPreviewSize = size;
+ break;
+ }
+ }
}
- }
-
- 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();
+ return mPreviewSize;
}
@Override
- void endVideo() {
- if (mMediaRecorder != null) {
- mMediaRecorder.stop();
- mMediaRecorder = null;
- }
-
- mCameraListener.onVideoTaken(mVideoFile);
-
+ boolean isCameraOpened() {
+ return mCamera != null;
}
- @Override
- void focus() {
- mCamera.autoFocus(null);
- }
+ // Internal:
- @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 void openCamera() {
+ if (mCamera != null) {
+ releaseCamera();
}
- }
- 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;
- }
+ mCamera = Camera.open(mCameraId);
+ mCameraParameters = mCamera.getParameters();
+
+ adjustCameraParameters();
+ mCamera.setDisplayOrientation(
+ calculateCameraRotation(mDisplayOrientation)
+ );
+
+ mCameraListener.onCameraOpened();
}
- private void setUpPreview() {
+ 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());
}
@@ -384,110 +260,70 @@ public class Camera1 extends CameraImpl {
}
}
- 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 void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.release();
+ mCamera = null;
+ mCameraListener.onCameraClosed();
}
}
- 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;
+ private int calculateCameraRotation(int rotation) {
+ if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+ return (360 - (mCameraInfo.orientation + rotation) % 360) % 360;
} else {
- desiredWidth = surfaceWidth;
- desiredHeight = surfaceHeight;
+ return (mCameraInfo.orientation - rotation + 360) % 360;
}
- 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 adjustCameraParameters() {
+ mCameraParameters.setPreviewSize(
+ getPreviewResolution().getWidth(),
+ getPreviewResolution().getHeight()
+ );
+
+ mPreview.setTruePreviewSize(
+ getPreviewResolution().getWidth(),
+ getPreviewResolution().getHeight()
+ );
+
+ mCameraParameters.setPictureSize(
+ getCaptureResolution().getWidth(),
+ getCaptureResolution().getHeight()
+ );
+
+ mCameraParameters.setRotation(
+ calculateCameraRotation(mDisplayOrientation)
+ + (mFacing == CameraKit.Constants.FACING_FRONT ? 180 : 0)
+ );
+
+ setContinuousFocus(mContinuousFocus);
+ setFlash(mFlash);
+
+ mCamera.setParameters(mCameraParameters);
}
- 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));
+ private TreeSet findCommonAspectRatios(List previewSizes, List captureSizes) {
+ Set previewAspectRatios = new HashSet<>();
+ for (Camera.Size size : previewSizes) {
+ if (size.width >= CameraKit.Internal.screenHeight && size.height >= CameraKit.Internal.screenWidth) {
+ previewAspectRatios.add(AspectRatio.of(size.width, size.height));
+ }
}
- adjustCameraParameters();
- mCamera.setDisplayOrientation(calcCameraRotation(mDisplayOrientation));
-
- mCameraListener.onCameraOpened();
- }
+ Set captureAspectRatios = new HashSet<>();
+ for (Camera.Size size : captureSizes) {
+ captureAspectRatios.add(AspectRatio.of(size.width, size.height));
+ }
- private void releaseCamera() {
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- mCameraListener.onCameraClosed();
+ TreeSet output = new TreeSet<>();
+ for (AspectRatio aspectRatio : previewAspectRatios) {
+ if (captureAspectRatios.contains(aspectRatio)) {
+ output.add(aspectRatio);
+ }
}
- }
- @Override
- Size getCaptureResolution() {
- return mCaptureSize;
+ return output;
}
- @Override
- Size getPreviewResolution() {
- return mPreviewSize;
- }
}
diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java b/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java
new file mode 100644
index 00000000..51dbcbb7
--- /dev/null
+++ b/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java
@@ -0,0 +1,62 @@
+package com.flurgle.camerakit;
+
+import android.hardware.Camera;
+import android.support.v4.util.SparseArrayCompat;
+
+public class ConstantMapper {
+
+ private abstract static class BaseMapper {
+
+ protected int mCameraKitConstant;
+
+ protected BaseMapper(int cameraKitConstant) {
+ this.mCameraKitConstant = cameraKitConstant;
+ }
+
+ abstract T map();
+
+ }
+
+ public static class Flash extends BaseMapper {
+
+ 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);
+ }
+
+ protected Flash(int cameraKitConstant) {
+ super(cameraKitConstant);
+ }
+
+ @Override
+ String map() {
+ return FLASH_MODES.get(mCameraKitConstant, FLASH_MODES.get(CameraKit.Constants.FLASH_OFF));
+ }
+
+ }
+
+ public static class Facing extends BaseMapper {
+
+ 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);
+ }
+
+ protected Facing(int cameraKitConstant) {
+ super(cameraKitConstant);
+ }
+
+ @Override
+ Integer map() {
+ return FACING_MODES.get(mCameraKitConstant, FACING_MODES.get(Camera.CameraInfo.CAMERA_FACING_BACK));
+ }
+
+ }
+
+
+}
diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/ProcessStillTask.java b/camerakit/src/main/api16/com/flurgle/camerakit/ProcessStillTask.java
new file mode 100644
index 00000000..3a6386ce
--- /dev/null
+++ b/camerakit/src/main/api16/com/flurgle/camerakit/ProcessStillTask.java
@@ -0,0 +1,55 @@
+package com.flurgle.camerakit;
+
+import android.graphics.YuvImage;
+import android.hardware.Camera;
+
+class ProcessStillTask implements Runnable {
+
+ private byte[] data;
+ private Camera camera;
+ private Camera.CameraInfo cameraInfo;
+ private 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 = new Rotation(data, width, height, rotation).getYuv();
+
+ 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);
+ }
+
+}
\ No newline at end of file
diff --git a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java
index 69fb49cf..3d01c0d3 100644
--- a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java
+++ b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java
@@ -1,493 +1,84 @@
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;
+class Camera2 extends CameraImpl {
-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();
- }
- }
- });
+ Camera2(CameraListener callback, PreviewImpl preview) {
+ super(callback, preview);
}
@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;
+ void setFacing(@Facing int facing) {
+
}
@Override
- void setFacing(int facing) {
- if (mFacing == facing) {
- return;
- }
- if (setFacingInternal(facing) && isCameraOpened()) {
- stop();
- start();
- }
- }
+ void setFlash(@Flash int flash) {
- 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;
- }
- }
+ @Override
+ void setContinuousFocus(boolean autoFocus) {
- return false;
}
@Override
- void setFlash(int flash) {
- if (flash == mFlash) {
- return;
- }
- if (setFlashInternal(flash)) {
- mCamera.setParameters(mCameraParameters);
- }
- }
+ void setDisplayOrientation(int displayOrientation) {
- 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);
- }
+ void focus() {
+
}
- 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));
- }
+ @Override
+ void zoom(float percentZoom) {
- 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);
+ Size getCaptureResolution() {
+ return 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();
- }
+ Size getPreviewResolution() {
+ return null;
}
@Override
- Size getCaptureResolution() {
- return mCaptureSize;
+ boolean isCameraOpened() {
+ return false;
}
- @Override
- Size getPreviewResolution() {
- return mPreviewSize;
- }
}
diff --git a/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
index df04432d..ade7ca15 100644
--- a/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
+++ b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
@@ -1,8 +1,8 @@
package com.flurgle.camerakit;
-public abstract class CameraImpl {
+abstract class CameraImpl {
- protected CameraListener mCameraListener;
+ protected final CameraListener mCameraListener;
protected final PreviewImpl mPreview;
CameraImpl(CameraListener callback, PreviewImpl preview) {
@@ -13,14 +13,13 @@ public abstract class CameraImpl {
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 void setContinuousFocus(boolean autoFocus);
abstract void setDisplayOrientation(int displayOrientation);
abstract void focus();
+ abstract void zoom(float percentZoom);
abstract void captureStandard();
abstract void captureStill();
@@ -30,5 +29,6 @@ public abstract class CameraImpl {
abstract Size getCaptureResolution();
abstract Size getPreviewResolution();
+ abstract boolean isCameraOpened();
}
diff --git a/camerakit/src/main/base/com/flurgle/camerakit/PreviewImpl.java b/camerakit/src/main/base/com/flurgle/camerakit/PreviewImpl.java
index 3850416f..25823927 100644
--- a/camerakit/src/main/base/com/flurgle/camerakit/PreviewImpl.java
+++ b/camerakit/src/main/base/com/flurgle/camerakit/PreviewImpl.java
@@ -5,7 +5,7 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
-public abstract class PreviewImpl {
+abstract class PreviewImpl {
interface Callback {
void onSurfaceChanged();
diff --git a/camerakit/src/main/base/com/flurgle/camerakit/TextureViewPreview.java b/camerakit/src/main/base/com/flurgle/camerakit/TextureViewPreview.java
index bca38e64..a0d5e57b 100644
--- a/camerakit/src/main/base/com/flurgle/camerakit/TextureViewPreview.java
+++ b/camerakit/src/main/base/com/flurgle/camerakit/TextureViewPreview.java
@@ -10,7 +10,7 @@ import android.view.View;
import android.view.ViewGroup;
@TargetApi(14)
-public class TextureViewPreview extends PreviewImpl {
+class TextureViewPreview extends PreviewImpl {
private final TextureView mTextureView;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
index 16b30b92..c08abbab 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
+++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java
@@ -1,7 +1,16 @@
package com.flurgle.camerakit;
+import android.content.res.Resources;
+
public class CameraKit {
+ static class Internal {
+
+ static final int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
+ static final int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+
+ }
+
public static class Constants {
public static final int FACING_BACK = 0;
diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
index 7cfc6e53..a749b2a4 100644
--- a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
+++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
@@ -27,13 +27,13 @@ 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.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 {
@@ -56,7 +56,7 @@ public class CameraView extends FrameLayout {
private boolean mCropOutput;
- private boolean mAutoFocus;
+ private boolean mContinuousFocus;
private float mCaptureSize;
@@ -80,49 +80,26 @@ public class CameraView extends FrameLayout {
public CameraView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
+
if (attrs != null) {
- TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CameraView);
- final int n = a.getIndexCount();
- for (int i = 0; i < n; ++i) {
- int attr = a.getIndex(i);
-
- if (attr == R.styleable.CameraView_ckFacing) {
- mFacing = a.getInteger(R.styleable.CameraView_ckFacing, FACING_BACK);
- }
-
- if (attr == R.styleable.CameraView_ckFlash) {
- mFlash = a.getInteger(R.styleable.CameraView_ckFlash, FLASH_OFF);
- }
-
- 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_ckAutoFocus) {
- mAutoFocus = a.getBoolean(R.styleable.CameraView_ckAutoFocus, true);
- }
-
- if (attr == R.styleable.CameraView_ckCaptureSize) {
- 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);
- }
+ TypedArray a = context.getTheme().obtainStyledAttributes(
+ attrs,
+ R.styleable.CameraView,
+ 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);
+ } finally {
+ a.recycle();
}
- a.recycle();
}
mCameraListener = new CameraListenerMiddleWare();
@@ -132,10 +109,10 @@ public class CameraView extends FrameLayout {
setFacing(mFacing);
setFlash(mFlash);
- setPictureMode(mCaptureMode);
+ setCaptureMode(mCaptureMode);
setCropOutput(mCropOutput);
setTapToFocus(mTapToFocus);
- setAutoFocus(mAutoFocus);
+ setContinuousFocus(mContinuousFocus);
setCaptureSize(mCaptureSize);
mDisplayOrientationDetector = new DisplayOrientationDetector(context) {
@@ -241,12 +218,12 @@ public class CameraView extends FrameLayout {
return mFlash;
}
- public void setPictureMode(@CaptureMode int pictureMode) {
- this.mCaptureMode = pictureMode;
+ public void setCaptureMode(@CaptureMode int captureMode) {
+ this.mCaptureMode = captureMode;
}
@CaptureMode
- public int getPictureMode() {
+ public int getCaptureMode() {
return mCaptureMode;
}
@@ -263,8 +240,9 @@ public class CameraView extends FrameLayout {
}
}
- public void setAutoFocus(boolean autoFocus) {
- this.mAutoFocus = autoFocus;
+ public void setContinuousFocus(boolean continuousFocus) {
+ this.mContinuousFocus = continuousFocus;
+ mCameraImpl.setContinuousFocus(continuousFocus);
}
public void setCaptureSize(float captureSize) {
diff --git a/camerakit/src/main/res/values/attrs.xml b/camerakit/src/main/res/values/attrs.xml
index 62ab920e..c16347e0 100644
--- a/camerakit/src/main/res/values/attrs.xml
+++ b/camerakit/src/main/res/values/attrs.xml
@@ -22,13 +22,15 @@
+
+
-
+
diff --git a/camerakit/src/main/res/values/strings.xml b/camerakit/src/main/res/values/strings.xml
deleted file mode 100644
index 252d7984..00000000
--- a/camerakit/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- CameraKit
-
diff --git a/camerakit/src/main/utils/com/flurgle/camerakit/CenterCrop.java b/camerakit/src/main/utils/com/flurgle/camerakit/CenterCrop.java
index 6b10bf7e..c368d2a2 100644
--- a/camerakit/src/main/utils/com/flurgle/camerakit/CenterCrop.java
+++ b/camerakit/src/main/utils/com/flurgle/camerakit/CenterCrop.java
@@ -17,7 +17,7 @@ public class CenterCrop {
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);
+ yuv.compressToJpeg(crop, jpegCompression, out);
this.croppedJpeg = out.toByteArray();
}
@@ -36,11 +36,10 @@ public class CenterCrop {
).decodeRegion(crop, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
- bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
+ bitmap.compress(Bitmap.CompressFormat.JPEG, jpegCompression, out);
this.croppedJpeg = out.toByteArray();
} catch (IOException e) {
Log.e("CameraKit", e.toString());
- return;
}
}
diff --git a/camerakit/src/main/utils/com/flurgle/camerakit/YuvUtils.java b/camerakit/src/main/utils/com/flurgle/camerakit/Rotation.java
similarity index 56%
rename from camerakit/src/main/utils/com/flurgle/camerakit/YuvUtils.java
rename to camerakit/src/main/utils/com/flurgle/camerakit/Rotation.java
index a41d82ab..4e6ee6e9 100644
--- a/camerakit/src/main/utils/com/flurgle/camerakit/YuvUtils.java
+++ b/camerakit/src/main/utils/com/flurgle/camerakit/Rotation.java
@@ -1,40 +1,11 @@
package com.flurgle.camerakit;
-import android.media.Image;
-import android.util.Log;
+public class Rotation {
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
+ private byte[] rotatedYuv;
-public class YuvUtils {
-
- public static byte[] getYUVData(Image image) {
- ByteBuffer bufferY = image.getPlanes()[0].getBuffer();
- byte[] y = new byte[bufferY.remaining()];
- bufferY.get(y);
-
- ByteBuffer bufferU = image.getPlanes()[1].getBuffer();
- byte[] u = new byte[bufferU.remaining()];
- bufferU.get(u);
-
- ByteBuffer bufferV = image.getPlanes()[2].getBuffer();
- byte[] v = new byte[bufferV.remaining()];
- bufferV.get(v);
-
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- try {
- outputStream.write(y);
- outputStream.write(v);
- outputStream.write(u);
- } catch (IOException e) {
- Log.e("CameraKit", e.toString());
- }
- return outputStream.toByteArray();
- }
-
- public static byte[] rotateNV21(final byte[] yuv, final int width, final int height, final int rotation) {
- if (rotation == 0) return yuv;
+ public Rotation(final byte[] yuv, final int width, final int height, final int rotation) {
+ if (rotation == 0) this.rotatedYuv = yuv;
if (rotation % 90 != 0 || rotation < 0 || rotation > 270) {
throw new IllegalArgumentException("0 <= rotation < 360, rotation % 90 == 0");
}
@@ -67,7 +38,12 @@ public class YuvUtils {
output[vOut] = (byte) (0xff & yuv[vIn]);
}
}
- return output;
+
+ this.rotatedYuv = output;
+ }
+
+ public byte[] getYuv() {
+ return this.rotatedYuv;
}
}
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 3aabf61d..0dabfaf8 100644
--- a/demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
+++ b/demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
@@ -191,7 +191,7 @@ public class MainActivity extends AppCompatActivity {
RadioGroup.OnCheckedChangeListener captureModeChangedListener = new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
- camera.setPictureMode(
+ camera.setCaptureMode(
checkedId == R.id.modeCaptureQuality ?
CameraKit.Constants.CAPTURE_MODE_STANDARD :
CameraKit.Constants.CAPTURE_MODE_STILL
diff --git a/demo/src/main/res/layout/activity_main.xml b/demo/src/main/res/layout/activity_main.xml
index a48ee39f..6643a168 100644
--- a/demo/src/main/res/layout/activity_main.xml
+++ b/demo/src/main/res/layout/activity_main.xml
@@ -18,10 +18,11 @@
android:layout_width="match_parent"
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:ckCaptureMode="standard"
app:ckTapToFocus="visible" />