feat: Implement exposure (#2173)

* feat: Implement `exposure` (iOS)

* Update Podfile.lock

* Format

* Expose exposure in format

* Set exposure in Camera2

* fix: Fix exposure calculation

* Add exposure docs
This commit is contained in:
Marc Rousavy
2023-11-19 15:26:43 +01:00
committed by GitHub
parent a7e706150e
commit ef58d13b87
19 changed files with 156 additions and 8 deletions

View File

@@ -46,6 +46,7 @@ public final class CameraView: UIView, CameraSessionDelegate {
@objc var isActive = false
@objc var torch = "off"
@objc var zoom: NSNumber = 1.0 // in "factor"
@objc var exposure: NSNumber = 1.0
@objc var enableFpsGraph = false
@objc var videoStabilizationMode: NSString?
@objc var resizeMode: NSString = "cover" {
@@ -218,6 +219,9 @@ public final class CameraView: UIView, CameraSessionDelegate {
// Zoom
config.zoom = zoom.doubleValue
// Exposure
config.exposure = exposure.floatValue
// isActive
config.isActive = isActive
}

View File

@@ -44,6 +44,7 @@ RCT_EXPORT_VIEW_PROPERTY(pixelFormat, NSString);
// other props
RCT_EXPORT_VIEW_PROPERTY(torch, NSString);
RCT_EXPORT_VIEW_PROPERTY(zoom, NSNumber);
RCT_EXPORT_VIEW_PROPERTY(exposure, NSNumber);
RCT_EXPORT_VIEW_PROPERTY(enableZoomGesture, BOOL);
RCT_EXPORT_VIEW_PROPERTY(enableFpsGraph, BOOL);
RCT_EXPORT_VIEW_PROPERTY(orientation, NSString);

View File

@@ -39,6 +39,9 @@ class CameraConfiguration {
// Zoom
var zoom: CGFloat?
// Exposure
var exposure: Float?
// isActive (Start/Stop)
var isActive = false
@@ -59,6 +62,7 @@ class CameraConfiguration {
enableLowLightBoost = other.enableLowLightBoost
torch = other.torch
zoom = other.zoom
exposure = other.exposure
isActive = other.isActive
audio = other.audio
} else {
@@ -77,6 +81,7 @@ class CameraConfiguration {
let sidePropsChanged: Bool
let torchChanged: Bool
let zoomChanged: Bool
let exposureChanged: Bool
let audioSessionChanged: Bool
@@ -113,6 +118,8 @@ class CameraConfiguration {
torchChanged = left?.isActive != right.isActive || left?.torch != right.torch
// zoom (depends on format)
zoomChanged = formatChanged || left?.zoom != right.zoom
// exposure (depends on format)
exposureChanged = formatChanged || left?.exposure != right.exposure
// audio session
audioSessionChanged = left?.audio != right.audio

View File

@@ -285,6 +285,20 @@ extension CameraSession {
device.videoZoomFactor = clamped
}
// pragma MARK: Exposure
/**
Configures exposure (`exposure`) as a bias that adjusts exposureTime and ISO.
*/
func configureExposure(configuration: CameraConfiguration, device: AVCaptureDevice) {
guard let exposure = configuration.exposure else {
return
}
let clamped = max(min(exposure, device.maxExposureTargetBias), device.minExposureTargetBias)
device.setExposureTargetBias(clamped)
}
// pragma MARK: Audio
/**

View File

@@ -154,13 +154,17 @@ class CameraSession: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVC
if difference.zoomChanged {
self.configureZoom(configuration: config, device: device)
}
// 8. Configure exposure bias
if difference.exposureChanged {
self.configureExposure(configuration: config, device: device)
}
}
}
// 8. Start or stop the session if needed
// 9. Start or stop the session if needed
self.checkIsActive(configuration: config)
// 9. Enable or disable the Torch if needed (requires session to be running)
// 10. Enable or disable the Torch if needed (requires session to be running)
if difference.torchChanged {
try self.withDeviceLock { device in
try self.configureTorch(configuration: config, device: device)