Auto Focus and Auto Exposure in AVFoundation on Custom Camera Layer
public func captureDevicePointOfInterestForPoint(pointInLayer: CGPoint) -> CGPoint
will give you the point for the device to focus on based on the settings of your AVCaptureVideoPreviewLayer. See the docs.
Swift: autoFocus/Expose and continuousAutoFocus/Exposure at the same time?
Figured it out. First I call a method on myViewDidAppear that sets my default focus and exposure mode:
@objc func setDefaultFocusAndExposure() {
if let device = AVCaptureDevice.default(for:AVMediaType.video) {
do {
try device.lockForConfiguration()
device.isSubjectAreaChangeMonitoringEnabled = true
device.focusMode = AVCaptureDevice.FocusMode.continuousAutoFocus
device.exposureMode = AVCaptureDevice.ExposureMode.continuousAutoExposure
device.unlockForConfiguration()
} catch {
// Handle errors here
print("There was an error focusing the device's camera")
}
}
}
The trick here was not to confuse autoFocus with continuousAutoFocus. This way by default it constantly observes the scene and sets the focus and exposure. Also isSubjectAreaChangeMonitorEnabled is a very important bit. This lets you register a notification to call a function when the scene changes focus or exposure-wise so that you can switch the focus mode. More on that soon.
In a touch on the screen can set the focus and exposure based on a point:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let bounds = UIScreen.main.bounds
let touchPoint = touches.first! as UITouch
let screenSize = bounds.size
let focusPoint = CGPoint(x: touchPoint.location(in: view).y / screenSize.height, y: 1.0 - touchPoint.location(in: view).x / screenSize.width)
if let device = AVCaptureDevice.default(for:AVMediaType.video) {
do {
try device.lockForConfiguration()
if device.isFocusPointOfInterestSupported {
device.focusPointOfInterest = focusPoint
device.focusMode = AVCaptureDevice.FocusMode.autoFocus
}
if device.isExposurePointOfInterestSupported {
device.exposurePointOfInterest = focusPoint
device.exposureMode = AVCaptureDevice.ExposureMode.autoExpose
}
device.unlockForConfiguration()
} catch {
// Handle errors here
print("There was an error focusing the device's camera")
}
}
}
Register the notification in viewDidLoad for setting back the focus and exposure mode to continuous. Here I'm just calling the function that sets the default settings of continuous:
NotificationCenter.default.addObserver(self,
selector: #selector(self.setDefaultFocusAndExposure),
name: NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange,
object: nil)
Don't forget to remove observers in NotificationCenter:
deinit {
NotificationCenter.default.removeObserver(self)
}
Related Topics
How to Convert This Opengl Pointer Math to Swift
How to Enable Only Numeric Digit Keyboard iOS Swift
Swift Lazy and Optional Properties
How Is It I Can Animate the Change in Bar Tint Color of a Uinavigationbar But Not a Uitabbar
How to Fill a Circle Color by Percentage Value
Skspritenode Does Not Let Touches Pass Through When Isuserinteractionenabled False
How to Remove the Black Border of a Textfield
Get All Urls for Resources in Sub-Directory in Swift
Setcollectionviewlayout' Animation Broken When Also Changing Collection View Frame
Swiftui Transition from Modal Sheet to Regular View with Navigation Link
How to Set Kerning (Spacing Between Characters) on Uinavigationbar Title - Swift or Objective-C
Traverse View Controller Hierarchy in Swift
How to Add Interactive Uilabels on Top of a Uiimageview
Swiftui Tabbedview Only Shows First Tab's Content
Swift Nfc Mifare - Nfciso7816Apdu Sendmifare Command Not Supported