diff --git a/patches/vision-camera-isp-off.patch b/patches/vision-camera-isp-off.patch new file mode 100644 index 0000000..b579d11 --- /dev/null +++ b/patches/vision-camera-isp-off.patch @@ -0,0 +1,65 @@ +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