2015-10-16 2 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

Swift 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

Awesomely ответил +1 ... большое спасибо –

+0

спасибо человеку. Отличный ответ ...! –

Смежные вопросы