AVCapturePhoto Почему мое фото всегда пустое?

Я пытаюсь реализовать пользовательскую камеру, похожую на Snapchat. Я не понимаю, почему мое изображение всегда равно нулю во время перехода. Может быть, свежий взгляд может помочь, так как я работаю над этим уже 2 дня...

Когда я нажимаю кнопку «Сделать фото» (чтобы запустить «livePhotoTapped»), приложение вылетает с ошибкой: фатальная ошибка: неожиданно найдено nil при развертывании необязательного значения, ссылаясь на то, что изображение равно нулю

Любая помощь будет приятно :)

@IBOutlet weak var cameraView: UIView!

//session to capture data
var captureSession = AVCaptureSession()
//which camera to use
var backFacingCamera: AVCaptureDevice?
var frontFacingCamera: AVCaptureDevice?
var currentDevice: AVCaptureDevice?

var stillImageOutput: AVCaptureStillImageOutput?
var stillImage: UIImage?

//camera preview layer
var cameraPreviewLayer: AVCaptureVideoPreviewLayer?


func setupCaptureSessionCamera() {
    //this makes sure to get full res of camera
    captureSession.sessionPreset = AVCaptureSession.Preset.photo

    var devices = AVCaptureDevice.devices(for: .video)

    //query available devices
    for device in devices {

        if device.position == .front {
            frontFacingCamera = device
        } else if device.position == .back {
            backFacingCamera = device
        }
    }//end iteration

    //set a default device
    currentDevice = backFacingCamera

    //configure session w output for capturing still img
    stillImageOutput = AVCaptureStillImageOutput()
    stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecType.jpeg]


    do {
        //capture the data from whichevr camera we r using..imagine as buffer to translate data into real world image
        let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)

        captureSession.addInput(captureDeviceInput)
        captureSession.addOutput(stillImageOutput!)

        //setup camera preview layer
        cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

        //add the preview to our specified view in the UI
        view.layer.addSublayer(cameraPreviewLayer!)
        cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        cameraPreviewLayer?.frame = cameraView.frame

        captureSession.startRunning()

    } catch let error {

        print(error)

    }//end do 
}

  @IBAction func livePhotoTapped(_ sender: UIButton) {

    let videoConnection = stillImageOutput?.connection(with: .video)

    //capture still image async
    stillImageOutput?.captureStillImageAsynchronously(from: videoConnection!, completionHandler: { (imageDataBuffer, error) in

        if let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: imageDataBuffer!, previewPhotoSampleBuffer: imageDataBuffer!) {

            self.stillImage = UIImage(data: imageData)
            self.performSegue(withIdentifier: "toPreviewPhoto", sender: self)
        }

    })
}

person user7804097    schedule 21.10.2017    source источник
comment
Ваш imageDataBuffer равен нулю? Добавьте print(imageDataBuffer) перед if let imageData =... и посмотрите, равен ли он нулю.   -  person 3stud1ant3    schedule 21.10.2017
comment
Куда вы звоните setupCaptureSessionCamera?   -  person Vini App    schedule 21.10.2017


Ответы (2)


Используйте так:

Для CMSampleBufferIsValid проверьте эту ссылку

@IBAction func livePhotoTapped(_ sender: UIButton) {

    let videoConnection = stillImageOutput?.connection(with: .video)

    //capture still image async
    stillImageOutput?.captureStillImageAsynchronously(from: videoConnection!, completionHandler: { (imageDataBuffer, error) in

        if error != nil {
            print("error \(error)")
        } else {
            if let imageBuffer = imageDataBuffer, CMSampleBufferIsValid(imageBuffer) {
                if let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: imageDataBuffer!, previewPhotoSampleBuffer: imageDataBuffer!) {

                    self.stillImage = UIImage(data: imageData)
                    self.performSegue(withIdentifier: "toPreviewPhoto", sender: self)
                }    
            } else {
                print("imageDataBuffer is nil or not valid")
            }
        }
    })
}
person Vini App    schedule 21.10.2017

Вы принудительно разворачиваете нулевой объект.

var currentDevice: AVCaptureDevice?

Похоже, этот метод устарел:

+ (NSArray<AVCaptureDevice *> *)devices NS_DEPRECATED(10_7, NA, 4_0, 10_0, "Use AVCaptureDeviceDiscoverySession instead.");

Вы пробовали "AVCaptureDeviceDiscoverySession"?

person Mozahler    schedule 22.10.2017