From d2d98314eef1b7eed1073b192137ac1020137cc2 Mon Sep 17 00:00:00 2001 From: Adam Serbinski Date: Thu, 4 Nov 2021 09:51:52 -0400 Subject: [PATCH] Upload from camera: pinch to zoom, apect ratio This implements pinch to zoom in the full range supported by the camera HAL, fixes aspect ration handling on rotation, and sets up for multiple resolution and aspect ratio support. Signed-off-by: Adam Serbinski --- app/build.gradle | 1 + .../talk/activities/TakePhotoActivity.java | 50 ++++++++++++++----- .../main/res/layout/activity_take_picture.xml | 5 +- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9e0328782..25c1699ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -187,6 +187,7 @@ dependencies { ktlint "com.pinterest:ktlint:0.43.0" implementation 'org.conscrypt:conscrypt-android:2.5.2' + implementation 'androidx.camera:camera-core:1.0.1' implementation 'androidx.camera:camera-camera2:1.0.1' implementation 'androidx.camera:camera-lifecycle:1.0.1' implementation 'androidx.camera:camera-view:1.0.0-alpha28' diff --git a/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java b/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java index 9922234ff..a3a693b94 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java @@ -32,6 +32,7 @@ import android.util.DisplayMetrics; import android.util.Log; import android.util.Size; import android.view.OrientationEventListener; +import android.view.ScaleGestureDetector; import android.view.Surface; import android.view.View; import android.widget.Toast; @@ -52,6 +53,7 @@ import java.util.concurrent.ExecutionException; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; +import androidx.camera.core.AspectRatio; import androidx.camera.core.Camera; import androidx.camera.core.ImageCapture; import androidx.camera.core.ImageCaptureException; @@ -76,6 +78,9 @@ public class TakePhotoActivity extends AppCompatActivity { private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss", Locale.ROOT); + private Camera camera; + private boolean crop = false, lowres = false; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -89,13 +94,12 @@ public class TakePhotoActivity extends AppCompatActivity { cameraProviderFuture.addListener(() -> { try { final ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); - final Preview preview = getPreview(); - final ImageCapture imageCapture = getImageCapture(); - final Camera camera = cameraProvider.bindToLifecycle( + + camera = cameraProvider.bindToLifecycle( this, viewModel.getCameraSelector(), - imageCapture, - preview); + getImageCapture(false, false), + getPreview(false)); viewModel.getTorchToggleButtonImageResource() .observe( @@ -110,11 +114,11 @@ public class TakePhotoActivity extends AppCompatActivity { binding.switchCamera.setOnClickListener((v) -> { viewModel.toggleCameraSelector(); cameraProvider.unbindAll(); - cameraProvider.bindToLifecycle( + camera = cameraProvider.bindToLifecycle( this, viewModel.getCameraSelector(), - imageCapture, - preview); + getImageCapture(crop, lowres), + getPreview(crop)); }); binding.retake.setOnClickListener((v) -> { Uri uri = (Uri) binding.photoPreview.getTag(); @@ -133,6 +137,22 @@ public class TakePhotoActivity extends AppCompatActivity { finish(); }); + ScaleGestureDetector mDetector = + new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener(){ + @Override + public boolean onScale(ScaleGestureDetector detector){ + float ratio = camera.getCameraInfo().getZoomState().getValue().getZoomRatio(); + float delta = detector.getScaleFactor(); + camera.getCameraControl().setZoomRatio(ratio * delta); + return true; + } + }); + binding.preview.setOnTouchListener((v, event) -> { + v.performClick(); + mDetector.onTouchEvent(event); + return true; + }); + // Enable enlarging the image more than default 3x maximumScale. // Medium scale adapted to make double-tap behaviour more consistent. binding.photoPreview.setMaximumScale(MAX_SCALE); @@ -182,8 +202,12 @@ public class TakePhotoActivity extends AppCompatActivity { binding.photoPreview.setVisibility(View.VISIBLE); } - private ImageCapture getImageCapture() { - final ImageCapture imageCapture = new ImageCapture.Builder().setTargetResolution(new Size(1080, 1920)).build(); + private ImageCapture getImageCapture(boolean crop, boolean lowres) { + final ImageCapture imageCapture; + if (lowres) imageCapture = new ImageCapture.Builder() + .setTargetResolution(new Size(crop ? 1080 : 1440, 1920)).build(); + else imageCapture = new ImageCapture.Builder() + .setTargetAspectRatio(crop ? AspectRatio.RATIO_16_9 : AspectRatio.RATIO_4_3).build(); orientationEventListener = new OrientationEventListener(this) { @Override @@ -288,9 +312,11 @@ public class TakePhotoActivity extends AppCompatActivity { return rotate; } - private Preview getPreview() { - Preview preview = new Preview.Builder().build(); + private Preview getPreview(boolean crop) { + Preview preview = new Preview.Builder() + .setTargetAspectRatio(crop ? AspectRatio.RATIO_16_9 : AspectRatio.RATIO_4_3).build(); preview.setSurfaceProvider(binding.preview.getSurfaceProvider()); + return preview; } diff --git a/app/src/main/res/layout/activity_take_picture.xml b/app/src/main/res/layout/activity_take_picture.xml index b3a9c7709..fd898ba12 100644 --- a/app/src/main/res/layout/activity_take_picture.xml +++ b/app/src/main/res/layout/activity_take_picture.xml @@ -32,14 +32,15 @@ + android:layout_height="match_parent" + app:scaleType="fitCenter" />