2015-10-16 110 views
7

我想捏缩放相机,但我遇到两个问题。首先,它允许用户放大太多的方式和太多的方式,其次,当我拍照时,它不会放大视图。这里是我的密码功能代码...捏缩放相机

func pinch(pinch: UIPinchGestureRecognizer) { 
    if let view = cameraView { 
     view.transform = CGAffineTransformScale(view.transform, 
      pinch.scale, pinch.scale) 
      pinch.scale = 1 
    } 

} 

如果您需要查看更多代码,告诉我。谢谢!

回答

7

我遇到了相机实现的相同问题。要解决这个问题,你需要了解两件事情。

  • 最大和最小变焦必须在一个值内,否则会导致相机变焦太大。
  • 与未保存放大图像的实际图像一样,这是常见的错误,很多在线解决方案都没有涵盖。这实际上是因为你只是改变视图的缩放而不是实际的AVCaptureDevice的缩放。

要改变,你需要像这样的两件事情:

func pinch(pinch: UIPinchGestureRecognizer) { 
    var device: AVCaptureDevice = self.videoDevice 
    var vZoomFactor = ((gestureRecognizer as! UIPinchGestureRecognizer).scale) 
    var error:NSError! 
     do{ 
      try device.lockForConfiguration() 
      defer {device.unlockForConfiguration()} 
      if (vZoomFactor <= device.activeFormat.videoMaxZoomFactor){ 
       device.videoZoomFactor = vZoomFactor 
      }else{ 
      NSLog("Unable to set videoZoom: (max %f, asked %f)", device.activeFormat.videoMaxZoomFactor, vZoomFactor); 
      } 
     }catch error as NSError{ 
      NSLog("Unable to set videoZoom: %@", error.localizedDescription); 
     }catch _{ 

     } 
} 

正如你可以看到我使用一个类变量的视频设备(videoDevice)来跟踪捕获设备的我使用为视觉组件。我将缩放限制在一个特定范围内,并改变设备上的缩放属性,而不是视图本身!

+3

有一两件事失踪。您必须跟踪当前的缩放系数,并将其用于应该设置的缩放系数的计算中。但是,谢谢你的伟大答案! – stonecompass

1
var device: AVCaptureDevice = self.backCamera 
    var vZoomFactor = sender.scale 
    var error:NSError! 
    do{ 
     try device.lockForConfiguration() 
     defer {device.unlockForConfiguration()} 
     if (vZoomFactor <= device.activeFormat.videoMaxZoomFactor) { 

      let desiredZoomFactor:CGFloat = vZoomFactor + atan2(sender.velocity, 5.0); 
      device.videoZoomFactor = max(1.0, min(desiredZoomFactor, device.activeFormat.videoMaxZoomFactor)); 
     } 
     else { 

      NSLog("Unable to set videoZoom: (max %f, asked %f)", device.activeFormat.videoMaxZoomFactor, vZoomFactor); 
     } 
    } 
    catch error as NSError{ 

     NSLog("Unable to set videoZoom: %@", error.localizedDescription); 
    } 
    catch _{ 

    } 
0

如果您需要手动zoomTo(2.0)功能,您可以使用此

// Create listener for Pinch to Zoom 
let pinchRecognizer = UIPinchGestureRecognizer(target: self, action:#selector(FSCameraView.pinchToZoom(_:))) 
pinchRecognizer.delegate = self 
self.previewViewContainer.addGestureRecognizer(pinchRecognizer) 

// set the zoom to a zoomed in mode from start 
setZoom(CGFloat(2.0) 



// and the functions 
func pinchToZoom(sender:UIPinchGestureRecognizer) { 
    var vZoomFactor = ((sender as! UIPinchGestureRecognizer).scale) 
    setZoom(vZoomFactor) 
} 

func setZoom(zoomFactor:CGFloat) { 
    var device: AVCaptureDevice = self.device! 
    var error:NSError! 
    do{ 
     try device.lockForConfiguration() 
     defer {device.unlockForConfiguration()} 
     if (zoomFactor <= device.activeFormat.videoMaxZoomFactor) { 

      let desiredZoomFactor:CGFloat = zoomFactor + atan2(sender.velocity, 5.0); 
      device.videoZoomFactor = max(1.0, min(desiredZoomFactor, device.activeFormat.videoMaxZoomFactor)); 
     } 
     else { 
      NSLog("Unable to set videoZoom: (max %f, asked %f)", device.activeFormat.videoMaxZoomFactor, zoomFactor); 
     } 
    } 
    catch error as NSError{ 
     NSLog("Unable to set videoZoom: %@", error.localizedDescription); 
    } 
    catch _{ 
    } 
} 
1

要在代理启迪乌帕德亚雅的回答展开,你也需要保存之前的变焦倍率来计算新的,你不希望每次你抬起你的手指,再次尝试缩放,缩放重置为正常。

// To track the zoom factor 
var prevZoomFactor: CGFloat = 1 

func pinch(pinch: UIPinchGestureRecognizer) { 
    var device: AVCaptureDevice = self.videoDevice 

    // Here we multiply vZoomFactor with the previous zoom factor if it exist. 
    // Else just multiply by 1 
    var vZoomFactor = pinch.scale * prevZoomFactor 

    // If the pinching has ended, update prevZoomFactor. 
    // Note that we set the limit at 1, because zoom factor cannot be less than 1 or the setting device.videoZoomFactor will crash 
    if sender.state == .ended { 
     prevZoomFactor = zoomFactor >= 1 ? zoomFactor : 1 
    } 

    do { 
     try device.lockForConfiguration() 
     defer {device.unlockForConfiguration()} 
     if (vZoomFactor <= device.activeFormat.videoMaxZoomFactor) { 
      device.videoZoomFactor = vZoomFactor 
     } else { 
      print("Unable to set videoZoom: (max \(device.activeFormat.videoMaxZoomFactor), asked \(vZoomFactor))") 
     } 
    } catch { 
     print("\(error.localizedDescription)") 
    } 
} 
+1

你好。如果vZoomFactor小于1.0,应用程序不会崩溃吗? –

14

雨燕3.0

let minimumZoom: CGFloat = 1.0 
let maximumZoom: CGFloat = 3.0 
var lastZoomFactor: CGFloat = 1.0 

func pinch(_ pinch: UIPinchGestureRecognizer) { 
    guard let device = videoDeviceInput.device else { return } 

    // Return zoom value between the minimum and maximum zoom values 
    func minMaxZoom(_ factor: CGFloat) -> CGFloat { 
     return min(min(max(factor, minimumZoom), maximumZoom), device.activeFormat.videoMaxZoomFactor) 
    } 

    func update(scale factor: CGFloat) { 
     do { 
      try device.lockForConfiguration() 
      defer { device.unlockForConfiguration() } 
      device.videoZoomFactor = factor 
     } catch { 
      print("\(error.localizedDescription)") 
     } 
    } 

    let newScaleFactor = minMaxZoom(pinch.scale * lastZoomFactor) 

    switch pinch.state { 
    case .began: fallthrough 
    case .changed: update(scale: newScaleFactor) 
    case .ended: 
     lastZoomFactor = minMaxZoom(newScaleFactor) 
     update(scale: lastZoomFactor) 
    default: break 
    } 
} 
+0

这对我有用,谢谢! – Kushagra

+0

非常好的回答了+1 ...非常感谢 –

+0

谢谢。完美的答案...! –