With a videoView: UIView
displaying the video, and cameraDevice: AVCaptureDevice
, the following seems to work for me:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
var touchPoint = touches.first as! UITouch
var screenSize = videoView.bounds.size
var focusPoint = CGPoint(x: touchPoint.locationInView(videoView).y / screenSize.height, y: 1.0 - touchPoint.locationInView(videoView.x / screenSize.width)
if let device = cameraDevice {
if(device.lockForConfiguration(nil)) {
if device.focusPointOfInterestSupported {
device.focusPointOfInterest = focusPoint
device.focusMode = AVCaptureFocusMode.AutoFocus
}
if device.exposurePointOfInterestSupported {
device.exposurePointOfInterest = focusPoint
device.exposureMode = AVCaptureExposureMode.AutoExpose
}
device.unlockForConfiguration()
}
}
}
Note that I had to swap the x
and y
coordinates, and remap the x
coord from 1 to 0 instead of 0 to 1 —?not sure why that should be the case but it seems to be necessary to get it to work right (though it's a little tricky to test it too).
Edit: Apple's documentation explains the reason for the coordinate transformation.
In addition, a device may support a focus point of interest. You test for support using focusPointOfInterestSupported. If it’s supported, you set the focal point using focusPointOfInterest. You pass a CGPoint where {0,0} represents the top left of the picture area, and {1,1} represents the bottom right in landscape mode with the home button on the right—this applies even if the device is in portrait mode.
In my example I had been using .ContinuousAutoFocus
and .ContinuousAutoExposure
, but the documentation indicates .AutoFocus
is the right choice. Oddly the documentation makes no mention of .AutoExpose
, but I'm using it in my code and it works fine.
I also modified my example code to include .focusPointOfInterestSupported
and .exposurePointOfInterestSupported
tests —?the documentation also mentions using the isFocusModeSupported:
and isExposureModeSupported:
methods for a given focus/exposure mode to test whether it is available on a given device before setting it, but I assume if the device supports the point of interest modes then it also supports the auto modes. It all seems to work fine in my app.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…