diff --git a/node_modules/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/outputs/HybridPhotoOutput.kt b/node_modules/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/outputs/HybridPhotoOutput.kt index 883fa50..e0248e8 100644 --- a/node_modules/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/outputs/HybridPhotoOutput.kt +++ b/node_modules/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/outputs/HybridPhotoOutput.kt @@ -1,7 +1,10 @@ package com.margelo.nitro.camera.hybrids.outputs +import android.hardware.camera2.CameraMetadata +import android.hardware.camera2.CaptureRequest import android.media.MediaActionSound import android.util.Log +import androidx.camera.camera2.interop.Camera2Interop import androidx.camera.core.CameraSelector import androidx.camera.core.ImageCapture import androidx.camera.core.resolutionselector.ResolutionSelector @@ -108,6 +111,21 @@ // Capture Mode (Quality, Speed, ...) val captureMode = options.qualityPrioritization.toCaptureMode() setCaptureMode(captureMode) + + // The ISP's own noise reduction and edge enhancement, off for every + // still (patches/vision-camera-isp-off.patch, the shutter-silent + // patch's twin). The vendor pair is tuned to hide sensor noise in a + // screen-sized JPEG and charges the fine detail for it; this app + // sharpens and grains the file itself with Skia, so it would rather + // have the texture and the noise than the wax. Camera2Interop because + // the CameraX builders have no typed setter for either key. DNG never + // passes through the ISP, so the option is a no-op on the RAW output. + Camera2Interop.Extender(this) + .setCaptureRequestOption( + CaptureRequest.NOISE_REDUCTION_MODE, + CameraMetadata.NOISE_REDUCTION_MODE_OFF, + ) + .setCaptureRequestOption(CaptureRequest.EDGE_MODE, CameraMetadata.EDGE_MODE_OFF) if (options.previewImageTargetSize != null) { setPostviewEnabled(true) diff --git a/modules/recipescam-ultrawide/android/src/main/java/com/locphamtran/recipescamera/ultrawide/UltraWideModule.kt b/modules/recipescam-ultrawide/android/src/main/java/com/locphamtran/recipescamera/ultrawide/UltraWideModule.kt index c4bf38d..39308e3 100644 --- a/modules/recipescam-ultrawide/android/src/main/java/com/locphamtran/recipescamera/ultrawide/UltraWideModule.kt +++ b/modules/recipescam-ultrawide/android/src/main/java/com/locphamtran/recipescamera/ultrawide/UltraWideModule.kt @@ -8,6 +8,7 @@ import android.hardware.camera2.CameraCaptureSession import android.hardware.camera2.CameraCharacteristics import android.hardware.camera2.CameraDevice import android.hardware.camera2.CameraManager +import android.hardware.camera2.CameraMetadata import android.hardware.camera2.CaptureRequest import android.hardware.camera2.CaptureResult import android.hardware.camera2.TotalCaptureResult @@ -554,6 +555,15 @@ class UltraWidePreviewView(context: Context, appContext: AppContext) : ExpoView( req.set(CaptureRequest.JPEG_ORIENTATION, sensorOrientation) req.set(CaptureRequest.FLASH_MODE, flashMode(flash)) req.set(CaptureRequest.CONTROL_AE_MODE, flashAeMode(flash)) + // The ISP's own noise reduction and edge enhancement, off for the + // ultra-wide still too (patches/vision-camera-isp-off.patch), so 0.5x + // lands in the same file as the other lenses: the app sharpens and + // grains with Skia, it does not want the vendor wax. + req.set( + CaptureRequest.NOISE_REDUCTION_MODE, + CameraMetadata.NOISE_REDUCTION_MODE_OFF + ) + req.set(CaptureRequest.EDGE_MODE, CameraMetadata.EDGE_MODE_OFF) // The live preview carries the EV as a hardware AE bias (see setEv); the // file must not, or the lens bias and the export's software gain would // stack into a double EV. Pin the bias off and let the precapture trigger