From 4c021caa8f04ccaf75f168d52233f6752afbf714 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Sun, 30 Jul 2017 20:33:25 +0200 Subject: [PATCH] White Balance support --- README.md | 18 ++++ .../api16/com/flurgle/camerakit/Camera1.java | 59 +++++++---- .../com/flurgle/camerakit/ConstantMapper.java | 100 +++++++----------- .../api21/com/flurgle/camerakit/Camera2.java | 20 ++-- .../com/flurgle/camerakit/CameraImpl.java | 3 +- .../flurgle/camerakit/CameraProperties.java | 14 --- .../java/com/flurgle/camerakit/CameraKit.java | 7 +- .../com/flurgle/camerakit/CameraView.java | 29 ++++- camerakit/src/main/res/values/attrs.xml | 8 ++ 9 files changed, 142 insertions(+), 116 deletions(-) delete mode 100644 camerakit/src/main/base/com/flurgle/camerakit/CameraProperties.java diff --git a/README.md b/README.md index 07ab1352..4c68e0c4 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ CameraKit is an easy to use utility to work with the Android Camera APIs. Everyt - [cameraZoomMode](#camerazoommode) - [cameraCropOutput](#cameracropoutput) - [cameraJpegQuality](#camerajpegquality) + - [cameraWhiteBalance](#camerawhitebalance) - [Permissions Behavior](#permissions-behavior) - [Dynamic Sizing Behavior](#dynamic-sizing-behavior) - [Center Crop](#center-crop) @@ -38,6 +39,9 @@ CameraKit is an easy to use utility to work with the Android Camera APIs. Everyt - `CAPTURE_METHOD_STANDARD`: an image captured normally using the camera APIs. - `CAPTURE_METHOD_FRAME`: a freeze frame of the `CameraView` preview (similar to SnapChat and Instagram) for devices with slower cameras - Built-in tap to focus +- EXIF support + - Automatically detected orientation tag + - Plug in location tags with `CameraView.setLocation(double, double)` - TODO: Built-in pinch to zoom ## Setup @@ -157,6 +161,7 @@ camera.setCameraListener(new CameraListener() { app:cameraCropOutput="true" app:cameraJpegQuality="100" app:cameraVideoQuality="480p" + app:cameraWhiteBalance="auto" android:adjustViewBounds="true" /> ``` @@ -171,6 +176,7 @@ camera.setCameraListener(new CameraListener() { |[`cameraCropOutput`](#cameracropoutput)|`setCropOutput()`|`true` `false`|`false`| |[`cameraJpegQuality`](#camerajpegquality)|`setJpegQuality()`|`0 <= n <= 100`|`100`| |[`cameraVideoQuality`](#cameravideoquality)|`setVideoQuality()`|`max480p` `max720p` `max1080p` `max2160p` `highest` `lowest`|`max480p`| +|[`cameraWhiteBalance`](#camerawhitebalance)|`setWhiteBalance()`|`auto` `incandescent` `fluorescent` `daylight` `cloudy`|`auto`| ### cameraFacing @@ -261,6 +267,18 @@ cameraView.setVideoQuality(CameraKit.Constants.VIDEO_QUALITY_HIGHEST); cameraView.setVideoQuality(CameraKit.Constants.VIDEO_QUALITY_QVGA); ``` +### cameraWhiteBalance + +Sets the desired white balance for the current session. + +```java +cameraView.setWhiteBalance(CameraKit.Constants.WHITE_BALANCE_AUTO); +cameraView.setWhiteBalance(CameraKit.Constants.WHITE_BALANCE_INCANDESCENT); +cameraView.setWhiteBalance(CameraKit.Constants.WHITE_BALANCE_FLUORESCENT); +cameraView.setWhiteBalance(CameraKit.Constants.WHITE_BALANCE_DAYLIGHT); +cameraView.setWhiteBalance(CameraKit.Constants.WHITE_BALANCE_CLOUDY); +``` + ## Permissions behavior `CameraView` needs two permissions: diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java index 3c6d9990..ff0db475 100644 --- a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java +++ b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java @@ -18,12 +18,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -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.CAPTURE_METHOD_STANDARD; import static com.flurgle.camerakit.CameraKit.Constants.CAPTURE_METHOD_FRAME; +import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_TAP_WITH_MARKER; @SuppressWarnings("deprecation") class Camera1 extends CameraImpl { @@ -37,7 +37,7 @@ class Camera1 extends CameraImpl { private int mCameraId; private Camera mCamera; private Camera.Parameters mCameraParameters; - private CameraProperties mCameraProperties; + private ExtraProperties mExtraProperties; private Camera.CameraInfo mCameraInfo; private Size mPreviewSize; private Size mCaptureSize; @@ -56,10 +56,12 @@ class Camera1 extends CameraImpl { @Method private int mMethod; @ZoomMode private int mZoom; @VideoQuality private int mVideoQuality; + @WhiteBalance private int mWhiteBalance; private double mLatitude; private double mLongitude; private Handler mHandler = new Handler(); + private ConstantMapper.MapperImpl mMapper = new ConstantMapper.Mapper1(); Camera1(CameraListener callback, PreviewImpl preview) { super(callback, preview); @@ -136,11 +138,7 @@ class Camera1 extends CameraImpl { @Override void setFacing(@Facing int facing) { - int internalFacing = new ConstantMapper.Facing(facing).map(); - if (internalFacing == -1) { - return; - } - + int internalFacing = mMapper.mapFacing(facing); for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) { Camera.getCameraInfo(i, mCameraInfo); if (mCameraInfo.facing == internalFacing) { @@ -157,31 +155,43 @@ class Camera1 extends CameraImpl { } } + @Override + void setWhiteBalance(@WhiteBalance int whiteBalance) { + int old = mWhiteBalance; + mWhiteBalance = whiteBalance; + if (mCameraParameters != null) { + List supported = mCameraParameters.getSupportedWhiteBalance(); + String internal = mMapper.mapWhiteBalance(whiteBalance); + if (supported != null && supported.contains(internal)) { + mCameraParameters.setWhiteBalance(internal); + mCamera.setParameters(mCameraParameters); + } else { + mWhiteBalance = old; + } + } + } + @Override void setFlash(@Flash int flash) { + int old = mFlash; + mFlash = flash; if (mCameraParameters != null) { List flashes = mCameraParameters.getSupportedFlashModes(); - String internalFlash = new ConstantMapper.Flash(flash).map(); + String internalFlash = mMapper.mapFlash(flash); if (flashes != null && flashes.contains(internalFlash)) { mCameraParameters.setFlashMode(internalFlash); - mFlash = flash; + mCamera.setParameters(mCameraParameters); } else { - String currentFlash = new ConstantMapper.Flash(mFlash).map(); - if (flashes == null || !flashes.contains(currentFlash)) { - mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); - mFlash = FLASH_OFF; - } + mFlash = old; } - - mCamera.setParameters(mCameraParameters); - } else { - mFlash = flash; } } + @Override void setFocus(@Focus int focus) { - this.mFocus = focus; + int old = mFocus; + mFocus = focus; switch (focus) { case FOCUS_CONTINUOUS: if (mCameraParameters != null) { @@ -190,17 +200,20 @@ class Camera1 extends CameraImpl { if (modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); } else { - setFocus(FOCUS_OFF); + mFocus = old; } } break; case FOCUS_TAP: + case FOCUS_TAP_WITH_MARKER: if (mCameraParameters != null) { attachFocusTapListener(); final List modes = mCameraParameters.getSupportedFocusModes(); if (modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + } else { + mFocus = old; } } break; @@ -318,8 +331,8 @@ class Camera1 extends CameraImpl { @Nullable @Override - CameraProperties getCameraProperties() { - return mCameraProperties; + ExtraProperties getExtraProperties() { + return mExtraProperties; } // Internal: @@ -424,7 +437,7 @@ class Camera1 extends CameraImpl { } private void collectCameraProperties() { - mCameraProperties = new CameraProperties(mCameraParameters.getVerticalViewAngle(), + mExtraProperties = new ExtraProperties(mCameraParameters.getVerticalViewAngle(), mCameraParameters.getHorizontalViewAngle()); } diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java b/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java index 6b92febf..59d6a173 100644 --- a/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java +++ b/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java @@ -6,96 +6,70 @@ import android.hardware.camera2.CameraCharacteristics; import android.support.v4.util.SparseArrayCompat; import android.util.SparseIntArray; -public class ConstantMapper { - - private abstract static class BaseMapper { +import java.util.Map; - protected int mCameraKitConstant; +public class ConstantMapper { - protected BaseMapper(int cameraKitConstant) { - this.mCameraKitConstant = cameraKitConstant; - } + static abstract class MapperImpl { - abstract T map(); + MapperImpl() {} + abstract T mapFlash(@Flash int internalConstant); + abstract T mapFacing(@Facing int internalConstant); + abstract T mapWhiteBalance(@WhiteBalance int internalConstant); } - static class Flash extends BaseMapper { - - private static final SparseArrayCompat FLASH_MODES = new SparseArrayCompat<>(); + static class Mapper1 extends MapperImpl { + private static final SparseArrayCompat FLASH = new SparseArrayCompat<>(); + private static final SparseArrayCompat WB = new SparseArrayCompat<>(); + private static final SparseArrayCompat FACING = 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); - FLASH_MODES.put(CameraKit.Constants.FLASH_TORCH, Camera.Parameters.FLASH_MODE_TORCH); - } - - protected Flash(int cameraKitConstant) { - super(cameraKitConstant); + FLASH.put(CameraKit.Constants.FLASH_OFF, Camera.Parameters.FLASH_MODE_OFF); + FLASH.put(CameraKit.Constants.FLASH_ON, Camera.Parameters.FLASH_MODE_ON); + FLASH.put(CameraKit.Constants.FLASH_AUTO, Camera.Parameters.FLASH_MODE_AUTO); + FLASH.put(CameraKit.Constants.FLASH_TORCH, Camera.Parameters.FLASH_MODE_TORCH); + FACING.put(CameraKit.Constants.FACING_BACK, Camera.CameraInfo.CAMERA_FACING_BACK); + FACING.put(CameraKit.Constants.FACING_FRONT, Camera.CameraInfo.CAMERA_FACING_FRONT); + WB.put(CameraKit.Constants.WHITE_BALANCE_AUTO, Camera.Parameters.WHITE_BALANCE_AUTO); + WB.put(CameraKit.Constants.WHITE_BALANCE_INCANDESCENT, Camera.Parameters.WHITE_BALANCE_INCANDESCENT); + WB.put(CameraKit.Constants.WHITE_BALANCE_FLUORESCENT, Camera.Parameters.WHITE_BALANCE_FLUORESCENT); + WB.put(CameraKit.Constants.WHITE_BALANCE_DAYLIGHT, Camera.Parameters.WHITE_BALANCE_DAYLIGHT); + WB.put(CameraKit.Constants.WHITE_BALANCE_CLOUDY, Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT); } @Override - String map() { - return FLASH_MODES.get(mCameraKitConstant, FLASH_MODES.get(CameraKit.Constants.FLASH_OFF)); - } - - } - - @TargetApi(21) - static class Flash2 extends BaseMapper { - - protected Flash2(int cameraKitConstant) { - super(cameraKitConstant); + T mapFlash(int internalConstant) { + return (T) FLASH.get(internalConstant, null); } @Override - String map() { - return null; - } - - } - - 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); + T mapFacing(int internalConstant) { + return (T) FACING.get(internalConstant, null); } @Override - Integer map() { - return FACING_MODES.get(mCameraKitConstant, FACING_MODES.get(CameraKit.Constants.FACING_BACK)); + T mapWhiteBalance(int internalConstant) { + return (T) WB.get(internalConstant, null); } - } - @TargetApi(21) - static class Facing2 extends BaseMapper { - - private static final SparseIntArray FACING_MODES = new SparseIntArray(); + static class Mapper2 extends MapperImpl { - static { - FACING_MODES.put(CameraKit.Constants.FACING_BACK, CameraCharacteristics.LENS_FACING_BACK); - FACING_MODES.put(CameraKit.Constants.FACING_FRONT, CameraCharacteristics.LENS_FACING_FRONT); + @Override + T mapWhiteBalance(@WhiteBalance int internalConstant) { + return null; } - protected Facing2(int cameraKitConstant) { - super(cameraKitConstant); + @Override + T mapFacing(@Facing int internalConstant) { + return null; } @Override - Integer map() { - return FACING_MODES.get(mCameraKitConstant, FACING_MODES.get(CameraKit.Constants.FACING_BACK)); + T mapFlash(@Flash int internalConstant) { + return null; } - } - } diff --git a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java index 92be2aa6..940d5441 100644 --- a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java +++ b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java @@ -31,7 +31,8 @@ class Camera2 extends CameraImpl { private Size mCaptureSize; private Size mPreviewSize; - private final HashMap mCameraPropertyMap = new HashMap<>(); + private ConstantMapper.MapperImpl mMapper = new ConstantMapper.Mapper2(); + private final HashMap mExtraPropertiesMap = new HashMap<>(); Camera2(CameraListener callback, PreviewImpl preview, Context context) { super(callback, preview); @@ -64,7 +65,7 @@ class Camera2 extends CameraImpl { } float w = size.getWidth(); float h = size.getHeight(); - mCameraPropertyMap.put(cameraId, new CameraProperties( + mExtraPropertiesMap.put(cameraId, new ExtraProperties( (float) Math.toDegrees(2*Math.atan(w/(maxFocus[0]*2))), (float) Math.toDegrees(2*Math.atan(h/(maxFocus[0]*2))) )); @@ -99,11 +100,7 @@ class Camera2 extends CameraImpl { @Override void setFacing(@Facing int facing) { - int internalFacing = new ConstantMapper.Facing(facing).map(); - if (internalFacing == -1) { - return; - } - + int internalFacing = mMapper.mapFacing(facing); final String[] ids; try { ids = mCameraManager.getCameraIdList(); @@ -164,6 +161,11 @@ class Camera2 extends CameraImpl { } + @Override + void setWhiteBalance(@WhiteBalance int whiteBalance) { + + } + @Override void setVideoQuality(int videoQuality) { @@ -248,11 +250,11 @@ class Camera2 extends CameraImpl { @Nullable @Override - CameraProperties getCameraProperties() { + ExtraProperties getExtraProperties() { if (mCamera == null) { return null; } - return mCameraPropertyMap.get(mCamera.getId()); + return mExtraPropertiesMap.get(mCamera.getId()); } // Internal diff --git a/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java index fe854e4f..8e285301 100644 --- a/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java +++ b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java @@ -24,6 +24,7 @@ abstract class CameraImpl { abstract void setMethod(@Method int method); abstract void setZoom(@ZoomMode int zoom); abstract void setVideoQuality(@VideoQuality int videoQuality); + abstract void setWhiteBalance(@WhiteBalance int whiteBalance); abstract void setLocation(double latitude, double longitude); abstract void captureImage(); @@ -36,6 +37,6 @@ abstract class CameraImpl { abstract boolean isCameraOpened(); @Nullable - abstract CameraProperties getCameraProperties(); + abstract ExtraProperties getExtraProperties(); } diff --git a/camerakit/src/main/base/com/flurgle/camerakit/CameraProperties.java b/camerakit/src/main/base/com/flurgle/camerakit/CameraProperties.java deleted file mode 100644 index 6af4d501..00000000 --- a/camerakit/src/main/base/com/flurgle/camerakit/CameraProperties.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.flurgle.camerakit; - -/** - * Simple pojo containing various camera properties. - */ -public class CameraProperties { - public final float verticalViewingAngle; - public final float horizontalViewingAngle; - - public CameraProperties(float verticalViewingAngle, float horizontalViewingAngle) { - this.verticalViewingAngle = verticalViewingAngle; - this.horizontalViewingAngle = horizontalViewingAngle; - } -} diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java index 994ea4cb..c491be43 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java @@ -59,6 +59,11 @@ public class CameraKit { public static final int VIDEO_QUALITY_LOWEST = 5; public static final int VIDEO_QUALITY_QVGA = 6; + public static final int WHITE_BALANCE_AUTO = 0; + public static final int WHITE_BALANCE_INCANDESCENT = 1; + public static final int WHITE_BALANCE_FLUORESCENT = 2; + public static final int WHITE_BALANCE_DAYLIGHT = 3; + public static final int WHITE_BALANCE_CLOUDY = 4; } static class Defaults { @@ -70,7 +75,7 @@ public class CameraKit { static final int DEFAULT_METHOD = Constants.CAPTURE_METHOD_STANDARD; static final int DEFAULT_PERMISSIONS = Constants.PERMISSIONS_PICTURE; static final int DEFAULT_VIDEO_QUALITY = Constants.VIDEO_QUALITY_480P; - + static final int DEFAULT_WHITE_BALANCE = Constants.WHITE_BALANCE_AUTO; 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 4fedc6f2..f6f575e1 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java @@ -80,10 +80,10 @@ public class CameraView extends FrameLayout implements LifecycleObserver { @Flash private int mFlash; @Focus private int mFocus; @Method private int mMethod; - @ZoomMode - private int mZoom; + @ZoomMode private int mZoom; @Permissions private int mPermissions; @VideoQuality private int mVideoQuality; + @WhiteBalance private int mWhiteBalance; private int mJpegQuality; private boolean mCropOutput; private boolean mAdjustViewBounds; @@ -116,6 +116,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver { mMethod = a.getInteger(R.styleable.CameraView_cameraCaptureMethod, CameraKit.Defaults.DEFAULT_METHOD); mZoom = a.getInteger(R.styleable.CameraView_cameraZoomMode, CameraKit.Defaults.DEFAULT_ZOOM); mPermissions = a.getInteger(R.styleable.CameraView_cameraPermissionPolicy, CameraKit.Defaults.DEFAULT_PERMISSIONS); + mWhiteBalance = a.getInteger(R.styleable.CameraView_cameraWhiteBalance, CameraKit.Defaults.DEFAULT_WHITE_BALANCE); mVideoQuality = a.getInteger(R.styleable.CameraView_cameraVideoQuality, CameraKit.Defaults.DEFAULT_VIDEO_QUALITY); mJpegQuality = a.getInteger(R.styleable.CameraView_cameraJpegQuality, CameraKit.Defaults.DEFAULT_JPEG_QUALITY); mCropOutput = a.getBoolean(R.styleable.CameraView_cameraCropOutput, CameraKit.Defaults.DEFAULT_CROP_OUTPUT); @@ -138,6 +139,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver { setZoom(mZoom); setPermissionPolicy(mPermissions); setVideoQuality(mVideoQuality); + setWhiteBalance(mWhiteBalance); if (!isInEditMode()) { mOrientationHelper = new OrientationHelper(context) { @@ -352,8 +354,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver { } @Nullable - public CameraProperties getCameraProperties() { - return mCameraImpl.getCameraProperties(); + public ExtraProperties getExtraProperties() { + return mCameraImpl.getExtraProperties(); } @@ -366,6 +368,24 @@ public class CameraView extends FrameLayout implements LifecycleObserver { mCameraImpl.setLocation(latitude, longitude); } + /** + * Sets desired white balance to current camera session. + * @param whiteBalance desired white balance behavior. + */ + public void setWhiteBalance(@WhiteBalance int whiteBalance) { + mWhiteBalance = whiteBalance; + mCameraImpl.setWhiteBalance(whiteBalance); + } + + /** + * Returns the current white balance behavior. + * @return white balance value. + */ + @WhiteBalance + public int getWhiteBalance() { + return mWhiteBalance; + } + @Facing public int getFacing() { return mFacing; @@ -373,7 +393,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver { public void setFacing(@Facing final int facing) { this.mFacing = facing; - run(new Runnable() { @Override public void run() { diff --git a/camerakit/src/main/res/values/attrs.xml b/camerakit/src/main/res/values/attrs.xml index ff6fdda3..0b193219 100644 --- a/camerakit/src/main/res/values/attrs.xml +++ b/camerakit/src/main/res/values/attrs.xml @@ -22,6 +22,14 @@ + + + + + + + +