diff --git a/package/android/src/main/java/com/mrousavy/camera/CameraView+TakePhoto.kt b/package/android/src/main/java/com/mrousavy/camera/CameraView+TakePhoto.kt index 7ba6775..9098074 100644 --- a/package/android/src/main/java/com/mrousavy/camera/CameraView+TakePhoto.kt +++ b/package/android/src/main/java/com/mrousavy/camera/CameraView+TakePhoto.kt @@ -30,10 +30,12 @@ suspend fun CameraView.takePhoto(optionsMap: ReadableMap): WritableMap { val qualityPrioritization = options["qualityPrioritization"] as? String ?: "balanced" val flash = options["flash"] as? String ?: "off" - val enableAutoRedEyeReduction = options["enableAutoRedEyeReduction"] == true val enableAutoStabilization = options["enableAutoStabilization"] == true val enableShutterSound = options["enableShutterSound"] as? Boolean ?: true + // TODO: Implement Red Eye Reduction + options["enableAutoRedEyeReduction"] + val flashMode = Flash.fromUnionValue(flash) val qualityPrioritizationMode = QualityPrioritization.fromUnionValue(qualityPrioritization) @@ -41,7 +43,6 @@ suspend fun CameraView.takePhoto(optionsMap: ReadableMap): WritableMap { qualityPrioritizationMode, flashMode, enableShutterSound, - enableAutoRedEyeReduction, enableAutoStabilization, orientation ) diff --git a/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt b/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt index 3d20edb..a589c26 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt @@ -58,7 +58,10 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, val cameraId val isMultiCam by lazy { capabilities.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) } val supportsDepthCapture by lazy { capabilities.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) } val supportsRawCapture by lazy { capabilities.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW) } - val supportsLowLightBoost by lazy { extensions.contains(CameraExtensionCharacteristics.EXTENSION_NIGHT) } + val supportsLowLightBoost by lazy { + extensions.contains(CameraExtensionCharacteristics.EXTENSION_NIGHT) && + modes.contains(CameraCharacteristics.CONTROL_MODE_USE_SCENE_MODE) + } val lensFacing by lazy { LensFacing.fromCameraCharacteristics(characteristics) } val hasFlash by lazy { characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) ?: false } val focalLengths by lazy { @@ -122,6 +125,7 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, val cameraId val supportsExposureRegions by lazy { (characteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE) ?: 0) > 0 } val supportsWhiteBalanceRegions by lazy { (characteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB) ?: 0) > 0 } + val modes by lazy { characteristics.get(CameraCharacteristics.CONTROL_AVAILABLE_MODES)?.toList() ?: emptyList() } val afModes by lazy { characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES)?.toList() ?: emptyList() } val aeModes by lazy { characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES)?.toList() ?: emptyList() } val awbModes by lazy { characteristics.get(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES)?.toList() ?: emptyList() } diff --git a/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt b/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt index ee9b2e5..893199e 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt @@ -368,7 +368,6 @@ class CameraSession(private val context: Context, private val cameraManager: Cam qualityPrioritization: QualityPrioritization, flash: Flash, enableShutterSound: Boolean, - enableRedEyeReduction: Boolean, enableAutoStabilization: Boolean, outputOrientation: Orientation ): CapturedPhoto { @@ -378,7 +377,6 @@ class CameraSession(private val context: Context, private val cameraManager: Cam val result = captureSession.capture( qualityPrioritization, flash, - enableRedEyeReduction, enableAutoStabilization, photoOutput.enableHdr, outputOrientation, diff --git a/package/android/src/main/java/com/mrousavy/camera/core/PersistentCameraCaptureSession.kt b/package/android/src/main/java/com/mrousavy/camera/core/PersistentCameraCaptureSession.kt index fc3276d..bca088d 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/PersistentCameraCaptureSession.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/PersistentCameraCaptureSession.kt @@ -140,7 +140,6 @@ class PersistentCameraCaptureSession(private val cameraManager: CameraManager, p suspend fun capture( qualityPrioritization: QualityPrioritization, flash: Flash, - enableRedEyeReduction: Boolean, enableAutoStabilization: Boolean, enablePhotoHdr: Boolean, orientation: Orientation, @@ -157,8 +156,6 @@ class PersistentCameraCaptureSession(private val cameraManager: CameraManager, p val photoRequest = PhotoCaptureRequest( repeatingRequest, qualityPrioritization, - flash, - enableRedEyeReduction, enableAutoStabilization, enablePhotoHdr, orientation @@ -195,6 +192,7 @@ class PersistentCameraCaptureSession(private val cameraManager: CameraManager, p // 2. Once precapture AF/AE/AWB successfully locked, capture the actual photo val singleRequest = photoRequest.createCaptureRequest(device, deviceDetails, outputs) if (result.needsFlash) { + singleRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON) singleRequest.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE) } return session.capture(singleRequest.build(), enableShutterSound) diff --git a/package/android/src/main/java/com/mrousavy/camera/core/capture/CameraCaptureRequest.kt b/package/android/src/main/java/com/mrousavy/camera/core/capture/CameraCaptureRequest.kt index fbf26cd..eeb5276 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/capture/CameraCaptureRequest.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/capture/CameraCaptureRequest.kt @@ -75,7 +75,7 @@ abstract class CameraCaptureRequest( } // Set Zoom - builder.setZoom(zoom, deviceDetails.characteristics) + builder.setZoom(zoom, deviceDetails) // Set Torch if (torch == Torch.ON) { diff --git a/package/android/src/main/java/com/mrousavy/camera/core/capture/PhotoCaptureRequest.kt b/package/android/src/main/java/com/mrousavy/camera/core/capture/PhotoCaptureRequest.kt index cfb5ae0..03ca3de 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/capture/PhotoCaptureRequest.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/capture/PhotoCaptureRequest.kt @@ -7,7 +7,6 @@ import android.os.Build import android.util.Log import com.mrousavy.camera.core.CameraDeviceDetails import com.mrousavy.camera.core.outputs.SurfaceOutput -import com.mrousavy.camera.types.Flash import com.mrousavy.camera.types.HardwareLevel import com.mrousavy.camera.types.Orientation import com.mrousavy.camera.types.QualityPrioritization @@ -16,8 +15,6 @@ import com.mrousavy.camera.types.Torch class PhotoCaptureRequest( repeatingRequest: RepeatingCaptureRequest, private val qualityPrioritization: QualityPrioritization, - private val flash: Flash, - private val enableRedEyeReduction: Boolean, private val enableAutoStabilization: Boolean, enablePhotoHdr: Boolean, private val outputOrientation: Orientation @@ -138,26 +135,6 @@ class PhotoCaptureRequest( val targetOrientation = outputOrientation.toSensorRelativeOrientation(deviceDetails) builder.set(CaptureRequest.JPEG_ORIENTATION, targetOrientation.toDegrees()) - // TODO: Fix flash. - when (flash) { - // Set the Flash Mode - Flash.OFF -> { - builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON) - builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF) - } - Flash.ON -> { - builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON) - builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH) - } - Flash.AUTO -> { - if (enableRedEyeReduction) { - builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) - } else { - builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH) - } - } - } - // Set stabilization for this Frame if (enableAutoStabilization) { if (deviceDetails.opticalStabilizationModes.contains(CameraCharacteristics.LENS_OPTICAL_STABILIZATION_MODE_ON)) { diff --git a/package/android/src/main/java/com/mrousavy/camera/core/capture/RepeatingCaptureRequest.kt b/package/android/src/main/java/com/mrousavy/camera/core/capture/RepeatingCaptureRequest.kt index b9a2f08..a95ca29 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/capture/RepeatingCaptureRequest.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/capture/RepeatingCaptureRequest.kt @@ -11,6 +11,7 @@ import com.mrousavy.camera.core.InvalidVideoStabilizationMode import com.mrousavy.camera.core.PropRequiresFormatToBeNonNullError import com.mrousavy.camera.core.outputs.SurfaceOutput import com.mrousavy.camera.types.CameraDeviceFormat +import com.mrousavy.camera.types.HardwareLevel import com.mrousavy.camera.types.Torch import com.mrousavy.camera.types.VideoStabilizationMode @@ -51,7 +52,9 @@ class RepeatingCaptureRequest( ): CaptureRequest.Builder { val builder = super.createCaptureRequest(template, device, deviceDetails, outputs) - builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO) + if (deviceDetails.modes.contains(CameraCharacteristics.CONTROL_MODE_AUTO)) { + builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO) + } // Set AF if (enableVideoPipeline && deviceDetails.afModes.contains(CameraCharacteristics.CONTROL_AF_MODE_CONTINUOUS_VIDEO)) { @@ -95,7 +98,11 @@ class RepeatingCaptureRequest( builder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, getBestDigitalStabilizationMode(deviceDetails)) } VideoStabilizationMode.CINEMATIC, VideoStabilizationMode.CINEMATIC_EXTENDED -> { - builder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON) + if (deviceDetails.hardwareLevel.isAtLeast(HardwareLevel.LIMITED)) { + builder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON) + } else { + builder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, getBestDigitalStabilizationMode(deviceDetails)) + } } else -> throw InvalidVideoStabilizationMode(videoStabilizationMode) } diff --git a/package/android/src/main/java/com/mrousavy/camera/extensions/CaptureRequest+setZoom.kt b/package/android/src/main/java/com/mrousavy/camera/extensions/CaptureRequest+setZoom.kt index 657886e..d097cbc 100644 --- a/package/android/src/main/java/com/mrousavy/camera/extensions/CaptureRequest+setZoom.kt +++ b/package/android/src/main/java/com/mrousavy/camera/extensions/CaptureRequest+setZoom.kt @@ -1,20 +1,18 @@ package com.mrousavy.camera.extensions -import android.hardware.camera2.CameraCharacteristics import android.hardware.camera2.CaptureRequest import android.os.Build -import android.util.Range +import com.mrousavy.camera.core.CameraDeviceDetails +import com.mrousavy.camera.types.HardwareLevel -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) +fun CaptureRequest.Builder.setZoom(zoom: Float, deviceDetails: CameraDeviceDetails) { + val zoomRange = deviceDetails.zoomRange + val zoomClamped = zoomRange.clamp(zoom) + + if (deviceDetails.hardwareLevel.isAtLeast(HardwareLevel.LIMITED) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { 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) + val size = deviceDetails.activeSize this.set(CaptureRequest.SCALER_CROP_REGION, size.zoomed(zoomClamped)) } }