fix: Incorrect zoom on Android < 11 (#1878)

* fix: Incorrect zoom on Android < 11

Fixes #1865

* Clamp zoom on Android

Some unclamped zoom values crash. For example, zoom={0.5} crashes
(tested on Android 9).

* Extract zoom into an extension (Android)

* Update package/android/src/main/java/com/mrousavy/camera/extensions/CaptureRequest+setZoom.kt

---------

Co-authored-by: Marc Rousavy <marcrousavy@hotmail.com>
This commit is contained in:
Touch Marine 2023-09-29 19:41:37 +02:00 committed by GitHub
parent 5a98716f31
commit fb812a6618
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 23 deletions

View File

@ -30,7 +30,7 @@ import com.mrousavy.camera.extensions.capture
import com.mrousavy.camera.extensions.createCaptureSession
import com.mrousavy.camera.extensions.createPhotoCaptureRequest
import com.mrousavy.camera.extensions.openCamera
import com.mrousavy.camera.extensions.zoomed
import com.mrousavy.camera.extensions.setZoom
import com.mrousavy.camera.frameprocessor.FrameProcessor
import com.mrousavy.camera.parsers.Flash
import com.mrousavy.camera.parsers.Orientation
@ -481,13 +481,8 @@ class CameraSession(
)
// Zoom
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
captureRequest.set(CaptureRequest.CONTROL_ZOOM_RATIO, zoom)
} else {
val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId!!)
val size = cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)!!
captureRequest.set(CaptureRequest.SCALER_CROP_REGION, size.zoomed(zoom))
}
captureRequest.setZoom(zoom, cameraCharacteristics)
// Torch Mode
val torchMode = if (torch == true) CaptureRequest.FLASH_MODE_TORCH else CaptureRequest.FLASH_MODE_OFF

View File

@ -4,7 +4,6 @@ import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraDevice
import android.hardware.camera2.CameraManager
import android.hardware.camera2.CaptureRequest
import android.os.Build
import android.view.Surface
import com.mrousavy.camera.parsers.Flash
import com.mrousavy.camera.parsers.Orientation
@ -86,12 +85,7 @@ fun CameraDevice.createPhotoCaptureRequest(
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
captureRequest.set(CaptureRequest.CONTROL_ZOOM_RATIO, zoom)
} else {
val size = cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)!!
captureRequest.set(CaptureRequest.SCALER_CROP_REGION, size.zoomed(zoom))
}
captureRequest.setZoom(zoom, cameraCharacteristics)
captureRequest.addTarget(surface)

View File

@ -0,0 +1,20 @@
package com.mrousavy.camera.extensions
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CaptureRequest
import android.os.Build
import android.util.Range
fun CaptureRequest.Builder.setZoom(zoom: Float, cameraCharacteristics: CameraCharacteristics) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val zoomRange = cameraCharacteristics.get(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE) ?: Range(1f, 1f)
val zoomClamped = zoomRange.clamp(zoom)
this.set(CaptureRequest.CONTROL_ZOOM_RATIO, zoomClamped)
} else {
val maxZoom = cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)
val zoomRange = Range(1f, maxZoom ?: 1f)
val size = cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)!!
val zoomClamped = zoomRange.clamp(zoom)
this.set(CaptureRequest.SCALER_CROP_REGION, size.zoomed(zoomClamped))
}
}

View File

@ -3,12 +3,11 @@ package com.mrousavy.camera.extensions
import android.graphics.Rect
fun Rect.zoomed(zoomFactor: Float): Rect {
val height = bottom - top
val width = right - left
val left = this.left + (width / zoomFactor / 2)
val top = this.top + (height / zoomFactor / 2)
val right = this.right - (width / zoomFactor / 2)
val bottom = this.bottom - (height / zoomFactor / 2)
return Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
val dx = (width() / zoomFactor / 2).toInt()
val dy = (height() / zoomFactor / 2).toInt()
val left = centerX() - dx
val top = centerY() - dy
val right = centerX() + dx
val bottom = centerY() + dy
return Rect(left, top, right, bottom)
}