xcode 使用 Swift 将相机焦点设置在点击点上
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26682450/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set Camera Focus On Tap Point With Swift
提问by Aggressor
The API for using the camera in swift seems a but different and I am having a hard time focusing the camera on a point. When the user taps the screen I want the camera to focus on that point
快速使用相机的 API 似乎有所不同,我很难将相机聚焦在一个点上。当用户点击屏幕时,我希望相机专注于该点
This is my code:
这是我的代码:
func focusCamera(point:CGPoint)
{
var screenRect:CGRect = bounds
var focusX = Float(point.x/screenRect.width)
var focusY = Float(point.y/screenRect.height)
_currentDevice.lockForConfiguration(nil)
_currentDevice.setFocusModeLockedWithLensPosition(focusX)
{
time in
self._currentDevice.unlockForConfiguration()
}
_currentDevice.setFocusModeLockedWithLensPosition(focusY)
{
time in
self._currentDevice.unlockForConfiguration()
}
}
But it doesnt seem to work.
但它似乎不起作用。
Any suggestions are more than welcome!
任何建议都非常受欢迎!
采纳答案by Aggressor
Turns out its very simple:
事实证明它非常简单:
_currentDevice.lockForConfiguration(nil)
_currentDevice.focusPointOfInterest = tap.locationInView(self)
_currentDevice.unlockForConfiguration()
回答by OxyFlax
Updated answer from @ryantxr for Swift 3:
来自@ryantxr 的 Swift 3 更新答案:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let screenSize = videoView.bounds.size
if let touchPoint = touches.first {
let x = touchPoint.location(in: videoView).y / screenSize.height
let y = 1.0 - touchPoint.location(in: videoView).x / screenSize.width
let focusPoint = CGPoint(x: x, y: y)
if let device = captureDevice {
do {
try device.lockForConfiguration()
device.focusPointOfInterest = focusPoint
//device.focusMode = .continuousAutoFocus
device.focusMode = .autoFocus
//device.focusMode = .locked
device.exposurePointOfInterest = focusPoint
device.exposureMode = AVCaptureExposureMode.continuousAutoExposure
device.unlockForConfiguration()
}
catch {
// just ignore
}
}
}
}
回答by fabb
Better solution, as it works correctly for all videoGravity
modes, also when the preview layer aspect ratio is different from the device ratio:
更好的解决方案,因为它适用于所有videoGravity
模式,也适用于预览层纵横比与设备比例不同的情况:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
guard let touchPoint = touches.first else { return }
// precondition: the videoView contains the previewLayer, and the frames of the two are being kept equal
let touchPointInPreviewLayer = touchPoint.location(in: videoView)
let focusPoint = previewLayer.captureDevicePointOfInterest(for: touchPointInPreviewLayer)
// etc
}
回答by ryantxr
Updated answer from @Code for Swift 2.
来自@Code for Swift 2 的更新答案。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let screenSize = videoView.bounds.size
if let touchPoint = touches.first {
let x = touchPoint.locationInView(videoView).y / screenSize.height
let y = 1.0 - touchPoint.locationInView(videoView).x / screenSize.width
let focusPoint = CGPoint(x: x, y: y)
if let device = captureDevice {
do {
try device.lockForConfiguration()
device.focusPointOfInterest = focusPoint
//device.focusMode = .ContinuousAutoFocus
device.focusMode = .AutoFocus
//device.focusMode = .Locked
device.exposurePointOfInterest = focusPoint
device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
device.unlockForConfiguration()
}
catch {
// just ignore
}
}
}
}
回答by gkhanacer
I used AVFoundation
library and a wrapper that Camera Manager.
I am sharing to code sample. You can adapt your project.
By the way, you cannot focus the camera using front-camera. It doesn't support it. You can only adjust exposure for front-camera. By rare-camera, you can do it.
我使用了AVFoundation
库和相机管理器的包装器。我正在分享代码示例。您可以调整您的项目。顺便说一下,您无法使用前置摄像头对相机进行对焦。它不支持它。您只能调整前置摄像头的曝光。用罕见的相机,你可以做到。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let screenSize = cameraView.bounds.size
let frameSize:CGSize = view.frame.size
if let touchPoint = touches.first {
var location:CGPoint = touchPoint.locationInView(cameraView)
if cameraManager.cameraDevice == .Front {
print("Front camera is used")
location.x = frameSize.width - location.x;
}
else {
print("Back camera is used")
}
let x = location.x / frameSize.width
let y = 1.0 - (location.x / frameSize.width)
let focusPoint = CGPoint(x: x, y: y)
print("POINT : X: \(x), Y: \(y)")
let captureDevice = (AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! [AVCaptureDevice]).filter{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)) {
device.focusPointOfInterest = focusPoint
device.focusMode = AVCaptureFocusMode.ContinuousAutoExposure
device.exposurePointOfInterest = focusPoint
device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
device.unlockForConfiguration()
}
}
}
.position == .Back}.first
if let device = captureDevice {
do {
try device.lockForConfiguration()
let support:Bool = device.focusPointOfInterestSupported
if support {
print("focusPointOfInterestSupported: \(support)")
device.focusPointOfInterest = focusPoint
// device.focusMode = .ContinuousAutoFocus
device.focusMode = .AutoFocus
// device.focusMode = .Locked
device.unlockForConfiguration()
print("Focus point was set successfully")
}
else{
print("focusPointOfInterestSupported is not supported: \(support)")
}
}
catch {
// just ignore
print("Focus point error")
}
}
}
}
回答by Cody
This question maybe is a duplicate of iOS tap to focus, where I posted this (hopefully explicit) solution that worked for me:
这个问题可能是iOS tap to focus的重复,我在那里发布了这个(希望是明确的)对我有用的解决方案:
With a videoView: UIView
displaying the video, and cameraDevice: AVCaptureDevice
, the following seems to work for me:
通过videoView: UIView
显示视频和cameraDevice: AVCaptureDevice
,以下内容似乎对我有用:
if let device = captureDevice {
do {
try device.lockForConfiguration()
device.focusPointOfInterest = focusPoint
device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus
device.exposurePointOfInterest = focusPoint
device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
} catch let error as NSError {
print(error.localizedDescription)
}
}
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).
请注意,我必须交换x
和y
坐标,并将坐标x
从 1重新映射到 0 而不是 0 到 1 - 不知道为什么会这样,但似乎有必要让它正常工作(尽管这有点棘手也测试一下)。
回答by Cody
Swift 2.0
斯威夫特 2.0
##代码##