iOS轻点焦点
我使用这个代码来实现在iOS自定义相机应用程序中的点击对焦,但它不工作。 这是代码
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { let touchPer = touches.anyObject() as UITouch let screenSize = UIScreen.mainScreen().bounds.size var focus_x = touchPer.locationInView(self.view).x / screenSize.width var focus_y = touchPer.locationInView(self.view).y / screenSize.height if let device = captureDevice { if(device.lockForConfiguration(nil)) { device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus device.focusPointOfInterest = CGPointMake(focus_x, focus_y) device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure device.unlockForConfiguration() } } }
使用videoView: UIView
显示video,以及cameraDevice: AVCaptureDevice
,以下似乎适用于我:
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() } } }
请注意,我必须交换x
和y
坐标,并将x
坐标从1重新映射到0,而不是0到1 – 不知道为什么应该是这种情况,但似乎有必要让它正常工作(尽pipe它有点棘手来testing它) 。
编辑: 苹果的文档解释了坐标转换的原因。
另外,设备可以支持焦点。 您使用focusPointOfInterestSupportedtesting支持。 如果支持,则使用focusPointOfInterest设置焦点。 您传递一个CGPoint,其中{0,0}代表图片区域的左上angular,{1,1}代表右侧的Homebutton在横向模式下的右下angular,即使设备处于纵向模式。
在我的示例中,我一直使用.ContinuousAutoFocus
和.AutoFocus
,但文档指出.AutoFocus
是正确的select。 奇怪的文件没有提及.AutoExpose
,但我在我的代码中使用它,它工作正常。
我还修改了我的示例代码,以包含.focusPointOfInterestSupported
和.exposurePointOfInterestSupported
testing – 文档中还提到使用isFocusModeSupported:
和isExposureModeSupported:
方法对于给定的焦点/曝光模式,在设置之前testing它是否在给定设备上可用,但是我假设设备是否支持兴趣点模式,那么它也支持自动模式。 这一切似乎在我的应用程序工作正常。
device.focusPointOfInterest = focusPoint device.focusMode = AVCaptureFocusMode.AutoFocus device.exposurePointOfInterest = focusPoint device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
我不这样做为什么这样做,但它做到了。
设定焦点的更好方法是:
-
首先计算兴趣点:
let devicePoint: CGPoint = (self.previewView.layer as! AVCaptureVideoPreviewLayer).captureDevicePointOfInterestForPoint(gestureRecognizer.locationInView(gestureRecognizer.view))
-
在那之后设定兴趣点:
let device: AVCaptureDevice! = self.videoDeviceInput!.device do { try device.lockForConfiguration() if device.focusPointOfInterestSupported && device.isFocusModeSupported(focusMode){ device.focusPointOfInterest = devicePoint device.focusMode = focusMode } device.unlockForConfiguration() }catch{ print(error) }
Swift 3.0解决scheme
将Cody的答案转换成Swift 3的工作解决scheme。
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { let touchPoint = touches.first! as UITouch let screenSize = cameraView.bounds.size let focusPoint = CGPoint(x: touchPoint.location(in: cameraView).y / screenSize.height, y: 1.0 - touchPoint.location(in: cameraView).x / screenSize.width) if let device = captureDevice { do { try device.lockForConfiguration() if device.isFocusPointOfInterestSupported { device.focusPointOfInterest = focusPoint device.focusMode = AVCaptureFocusMode.autoFocus } if device.isExposurePointOfInterestSupported { device.exposurePointOfInterest = focusPoint device.exposureMode = AVCaptureExposureMode.autoExpose } device.unlockForConfiguration() } catch { // Handle errors here } } }
您必须按正确的顺序调用方法:
if(device.lockForConfiguration(nil)) { device.focusPointOfInterest = CGPointMake(focus_x, focus_y) device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure device.unlockForConfiguration() }
在设置焦点模式之前设置兴趣点,否则焦点将在前一个兴趣点上进行。
这同样适用于exposurePointOfInterest
。