Пинч для увеличения камеры

Я пытаюсь сделать снимок для увеличения камеры, но у меня возникают две проблемы. Во-первых, это позволяет пользователю слишком много масштабировать и значительно увеличивать, во-вторых, когда я делаю снимок, он не воспринимает увеличенное изображение. Вот мой код для функции пинча...

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

}

Скажите, пожалуйста, если вам нужно больше кода. Спасибо!

Ответ 1

У меня возникли те же проблемы с реализацией камеры. Чтобы решить эту проблему, вам нужно знать о двух вещах.

  • Максимальное и минимальное масштабирование должно быть в пределах значения, иначе это приведет к слишком большому увеличению изображения камеры.
  • Как и фактическое изображение, не сохраняющее увеличенное изображение, это обычная ошибка, которую множество решений в Интернете не распространяется. Это происходит из-за того, что вы изменяете масштаб изображения, а не фактическое масштабирование 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), чтобы отслеживать устройство захвата, которое я использую для визуального компонента. Я ограничиваю масштаб до определенного диапазона и изменяю свойство масштабирования на устройстве, а не на самом представлении!

Ответ 2

Swift 3.0 || 4,0


1. Определите уровни масштабирования.

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


2. Добавьте жест Pinch на CameraView.

let pinchRecognizer = UIPinchGestureRecognizer(target: self, action:#selector(pinch(_:)))        
            self.viewCamera.addGestureRecognizer(pinchRecognizer)


3. Метод zoomin -действия с логикой zoomin и zoom out

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
        }
    }


Благодарю. Удачного кодирования 👍🏼

Ответ 3

    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 _{

    }

Ответ 4

Если вам нужна ручная функция 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 _{
    }
}

Ответ 5

Чтобы расширить ответ Ritvik Upadhyaya, вам также необходимо сохранить предыдущий коэффициент масштабирования для расчета нового, вы не хотите, чтобы масштабирование до reset было нормальным каждый раз, когда вы поднимаете вверх по пальцам и повторите попытку масштабирования.

// 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)")
    }
}