Получение фотоданных из AVCapturePhotoCaptureDelegate

В настоящее время я пытаюсь создать приложение для камеры для развлечения и столкнулся с проблемой.

Я использовал пример, который Apple предоставляет вам для процесса съемки фото или видео. Найдено здесь:

https://developer.apple.com/library/content/samplecode/AVCam/Introduction/Intro.html

У меня проблема с использованием PhotoCaptureDelegate. Итак, в настоящее время, когда пользователь делает фотографию, она сохраняется в библиотеке фотографий пользователя. Что я хотел бы сделать, так это то, что после того, как он сделает снимок, я хочу сохранить photoData объект фотографии. Чтобы я мог отобразить фотографию на другом виде в качестве предварительного просмотра, прежде чем сохранить ее.

Это то, что Apple предлагает использовать:

  func capture(_ captureOutput: AVCapturePhotoOutput, didFinishCaptureForResolvedSettings resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) {
    if let error = error {
        print("Error capturing photo: \(error)")
        didFinish()
        return
    }

    guard let photoData = photoData else {
        print("No photo data resource")
        didFinish()
        return
    }

    PHPhotoLibrary.requestAuthorization { [unowned self] status in
        if status == .authorized {
            PHPhotoLibrary.shared().performChanges({ [unowned self] in
                    let creationRequest = PHAssetCreationRequest.forAsset()
                    creationRequest.addResource(with: .photo, data: photoData, options: nil)

                    if let livePhotoCompanionMovieURL = self.livePhotoCompanionMovieURL {
                        let livePhotoCompanionMovieFileResourceOptions = PHAssetResourceCreationOptions()
                        livePhotoCompanionMovieFileResourceOptions.shouldMoveFile = true
                        creationRequest.addResource(with: .pairedVideo, fileURL: livePhotoCompanionMovieURL, options: livePhotoCompanionMovieFileResourceOptions)
                    }

                }, completionHandler: { [unowned self] success, error in
                    if let error = error {
                        print("Error occurered while saving photo to photo library: \(error)")
                    }

                    self.didFinish()
                }
            )
        }
        else {
            self.didFinish()
        }
    }
}

Как мне взять объект photoData из моего делегата и передать его обратно в мой контроллер представления, который вызывает этот делегат?


person scouty    schedule 29.01.2017    source источник


Ответы (1)


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

1) Передайте фото обратно

Есть (опять же) несколько способов сделать это. Вы можете попросить делегата передать значение контроллеру. Вы также можете попросить делегата сообщить контролеру, что все готово, и попросить контролера прийти и сделать снимок. Я объясню второй способ ниже.

Глядя на пример Apple, мы видим, что PhotoCaptureDelegate уже сообщает контроллеру, когда это будет сделано! Всякий раз, когда создается объект PhotoCaptureDelegate, ему передается блок completed.

Чтобы позволить контроллеру захватить фотографию, нам просто нужно сделать объект фотографии общедоступным!

  1. Измените private var photoData: Data? = nil в PhotoCaptureDelegate на public var photoData: Data? = nil
  2. В CameraViewController, когда вы определяете блок completed, у вас теперь есть фотоданные:
    ...
    , completed: { [unowned self] photoCaptureDelegate in
        self.sessionQueue.async { [unowned self] in
            self.inProgressPhotoCaptureDelegates[photoCaptureDelegate.requestedPhotoSettings.uniqueID] = nil
            if let photoData = photoCaptureDelegate.photoData {
                // You now have the photo data!
                // You can pass this to another method in the Controller now                
            }
        }
    }
    ...

2) View Controller как AVCapturePhotoCaptureDelegate

Другой способ решить эту проблему — просто сделать ViewController вашим AVCapturePhotoCaptureDelegate. Тогда у вас уже будут фотоданные в контроллере представления! Это может выглядеть примерно так:

class MyViewController: UIViewController, AVCapturePhotoCaptureDelegate {

    ...

    func capture(_ captureOutput: AVCapturePhotoOutput, didFinishCaptureForResolvedSettings resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) {
        guard let photoData = photoData else {
            return
        }
        // You now have your photo data!
    }
}
person Carter    schedule 29.01.2017
comment
Спасибо большое, давно мучаюсь с этим!!!! - person scouty; 29.01.2017