Swift: autoFocus/Expose 和 continuousAutoFocus/Exposure 同时?
Swift: autoFocus/Expose and continuousAutoFocus/Exposure at the same time?
现在在我的相机应用程序中,我让用户触摸任何地方来设置焦点和曝光,但我怎样才能像 Apple 的相机应用程序一样兼得两全其美呢?
例如,用户可能想通过触摸来对焦前景中的某物,但如果场景变化足够大,则应返回到连续自动对焦。同样,如果用户将相机指向一盏灯,它应该改变曝光以使其正确显示,然后当相机返回场景时它应该再次修复曝光以使其不会太暗。但是,他们仍然可以根据他们通过摄像头的视野触摸到的内容,将其调亮或调暗一些。
现在,当视图出现时,我将默认设置设置为屏幕中央:
func setDefaultFocusAndExposure() {
let focusPoint = CGPoint(x:0.5,y:0.5)
if let device = AVCaptureDevice.default(for:AVMediaType.video) {
do {
try device.lockForConfiguration()
if device.isFocusPointOfInterestSupported {
print(focusPoint)
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")
}
}
}
我还让用户根据触摸的位置设置焦点和曝光:
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")
}
}
}
想通了。首先,我在 myViewDidAppear 上调用一个方法来设置我的默认焦点和曝光模式:
@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")
}
}
}
这里的诀窍是不要将自动对焦与连续自动对焦混淆。这样默认情况下它会不断观察场景并设置焦点和曝光。 isSubjectAreaChangeMonitorEnabled 也是一个非常重要的位。这使您可以注册通知以在场景更改焦点或 exposure-wise 时调用函数,以便您可以切换焦点模式。稍后会详细介绍。
在触摸屏上可以根据一点设置对焦和曝光:
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")
}
}
}
在 viewDidLoad 中注册通知以将焦点和曝光模式设置回连续。这里我只是调用设置连续默认设置的函数:
NotificationCenter.default.addObserver(self,
selector: #selector(self.setDefaultFocusAndExposure),
name: NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange,
object: nil)
不要忘记在 NotificationCenter 中删除观察者:
deinit {
NotificationCenter.default.removeObserver(self)
}
现在在我的相机应用程序中,我让用户触摸任何地方来设置焦点和曝光,但我怎样才能像 Apple 的相机应用程序一样兼得两全其美呢?
例如,用户可能想通过触摸来对焦前景中的某物,但如果场景变化足够大,则应返回到连续自动对焦。同样,如果用户将相机指向一盏灯,它应该改变曝光以使其正确显示,然后当相机返回场景时它应该再次修复曝光以使其不会太暗。但是,他们仍然可以根据他们通过摄像头的视野触摸到的内容,将其调亮或调暗一些。
现在,当视图出现时,我将默认设置设置为屏幕中央:
func setDefaultFocusAndExposure() {
let focusPoint = CGPoint(x:0.5,y:0.5)
if let device = AVCaptureDevice.default(for:AVMediaType.video) {
do {
try device.lockForConfiguration()
if device.isFocusPointOfInterestSupported {
print(focusPoint)
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")
}
}
}
我还让用户根据触摸的位置设置焦点和曝光:
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")
}
}
}
想通了。首先,我在 myViewDidAppear 上调用一个方法来设置我的默认焦点和曝光模式:
@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")
}
}
}
这里的诀窍是不要将自动对焦与连续自动对焦混淆。这样默认情况下它会不断观察场景并设置焦点和曝光。 isSubjectAreaChangeMonitorEnabled 也是一个非常重要的位。这使您可以注册通知以在场景更改焦点或 exposure-wise 时调用函数,以便您可以切换焦点模式。稍后会详细介绍。
在触摸屏上可以根据一点设置对焦和曝光:
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")
}
}
}
在 viewDidLoad 中注册通知以将焦点和曝光模式设置回连续。这里我只是调用设置连续默认设置的函数:
NotificationCenter.default.addObserver(self,
selector: #selector(self.setDefaultFocusAndExposure),
name: NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange,
object: nil)
不要忘记在 NotificationCenter 中删除观察者:
deinit {
NotificationCenter.default.removeObserver(self)
}