From 820d9dd5ab66f9e4486f6ce4deca0ac9790920ad Mon Sep 17 00:00:00 2001 From: Suneet Agrawal Date: Tue, 2 Jul 2019 16:46:37 +0530 Subject: [PATCH] zoom implementation in Camera2Engine --- .../cameraview/CameraOptions.java | 17 ++++++- .../cameraview/engine/Camera2Engine.java | 50 ++++++++++++++++--- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraOptions.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraOptions.java index ca9dd397..e18bb76e 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraOptions.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraOptions.java @@ -56,6 +56,7 @@ public class CameraOptions { private Set supportedVideoAspectRatio = new HashSet<>(3); private boolean zoomSupported; + private float maxZoomValue; private boolean exposureCorrectionSupported; private float exposureCorrectionMinValue; private float exposureCorrectionMaxValue; @@ -202,7 +203,10 @@ public class CameraOptions { //zoom Float maxZoom = cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM); - zoomSupported = maxZoom != null && maxZoom > 1; + if(maxZoom != null) { + maxZoomValue = maxZoom; + zoomSupported = maxZoomValue > 1; + } // autofocus @@ -481,4 +485,15 @@ public class CameraOptions { public float getExposureCorrectionMaxValue() { return exposureCorrectionMaxValue; } + + /** + * The maximum value of digital zoom available by Hardware. + * This is presumably 1 and above than 1 in case zoom is avaible. + * + * @return max zoom value + */ + @SuppressWarnings("WeakerAccess") + public float getMaxZoomValue() { + return maxZoomValue; + } } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java index 25ea44d4..c0c175b4 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -23,6 +23,11 @@ import android.os.Build; import android.view.Surface; import android.view.SurfaceHolder; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.annotation.WorkerThread; + import com.google.android.gms.tasks.Task; import com.google.android.gms.tasks.TaskCompletionSource; import com.google.android.gms.tasks.Tasks; @@ -58,11 +63,6 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.annotation.WorkerThread; - // TODO full2picture fix rotation // TODO full2picture add shutter // TODO full2picture see if we don't launch activity @@ -902,8 +902,44 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv } @Override - public void setZoom(float zoom, @Nullable PointF[] points, boolean notify) { - // TODO + public void setZoom(final float zoom, final @Nullable PointF[] points, final boolean notify) { + mHandler.run(new Runnable() { + @Override + public void run() { + if (!mCameraOptions.isZoomSupported()) return; + + Rect newRect = getZoomRect(zoom); + if(newRect != null){ + mRepeatingRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, newRect); + applyRepeatingRequestBuilder(); + mZoomValue = zoom; + + if (notify) { + mCallback.dispatchOnZoomChanged(zoom, points); + } + } + } + }); + } + + private Rect getZoomRect(float zoomLevel) { + + float maxZoom = mCameraOptions.getMaxZoomValue() * 10; + Rect activeRect = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); + if ((zoomLevel <= maxZoom) && (zoomLevel > 1) && activeRect != null) { + int minW = (int) (activeRect.width() / maxZoom); + int minH = (int) (activeRect.height() / maxZoom); + int difW = activeRect.width() - minW; + int difH = activeRect.height() - minH; + int cropW = difW / 100 * (int) zoomLevel; + int cropH = difH / 100 * (int) zoomLevel; + cropW -= cropW & 3; + cropH -= cropH & 3; + return new Rect(cropW, cropH, activeRect.width() - cropW, activeRect.height() - cropH); + } else if (zoomLevel == 0) { + return new Rect(0, 0, activeRect.width(), activeRect.height()); + } + return null; } @Override