ios - 如何将拍摄的照片放到主线程?

标签 ios swift grand-central-dispatch avcapturesession

我有一个通过 captureStillImageAsynchronouslyFromConnection() 方法用相机拍摄照片的功能。 捕获的图像是我的 capture() 方法的返回值。

我想将捕获的照片保存到 ViewController 中的变量中,然后执行到另一个 ViewController 的 segue,这将显示照片。这似乎不起作用,我收到一个 fatal error :在展开可选值时意外发现 nil - 错误。

我知道这是因为 var photo: UIImage!nil,但是如何在调用 之前将照片数据获取到我的主线程中>performSegue... 函数?

我的照片功能(在我的 CameraSession 类中)和 session 队列:

var sessionQueue = dispatch_queue_create("CameraSession", DISPATCH_QUEUE_SERIAL) 

func capture(saveToGallery save: Bool) -> UIImage {
    var capturedImage = UIImage()

    let connection = self.output.connectionWithMediaType(AVMediaTypeVideo)
    connection.videoOrientation = .Portrait

    dispatch_async(sessionQueue, {
        self.output.captureStillImageAsynchronouslyFromConnection(
            connection, completionHandler: {
                (imageDataSampleBuffer: CMSampleBuffer?, error: NSError?) -> Void in
                if imageDataSampleBuffer != nil {
                    let imageData: NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
                         self.capturedImage = UIImage(data: imageData)

                    if save {
                        UIImageWriteToSavedPhotosAlbum(self.capturedImage!, nil, nil, nil)
                    }
                }
            }
        )
    })

    return self.capturedImage!
}

我在 ViewController 类中的函数:

func capture() {
    let photo = cameraSession.capture(saveToGallery: true)
    performSegueWithIdentifier("showPhoto", sender: self) // This will switch to another ViewController, which shows the captured photo.
}

最佳答案

由于您正在异步捕获照片,因此您的函数将达到

return self.capturedImage!

在拍摄照片之前,self.capturedImage 为零。您应该在图像数据返回后将处理 Segue 的逻辑移至某处。通过将回调作为参数添加到捕获方法中,这可能是最容易实现的:

func capture(saveToGallery save: Bool, callback:UIImage -> Void) -> Void

然后不要直接返回 UIImage,而是将其作为参数传递给回调:

let imageData: NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
    self.capturedImage = UIImage(data: imageData)

if save {
    UIImageWriteToSavedPhotosAlbum(self.capturedImage!, nil, nil, nil)
}

callback(self.capturedImage)

你的 UIViewController 捕获方法看起来像:

func capture() {
    let photo = cameraSession.capture(saveToGallery: true, callback: {
    (photo: UIImage) -> Void in
    //save your photo locally in your UIViewController class here if you need to
    performSegueWithIdentifier("showPhoto", sender: self)
    })
}

关于ios - 如何将拍摄的照片放到主线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37714370/

相关文章:

ios - 在application:didFinishLaunchingWithOptions之后执行选择器?

ios - 使用 UIScrollView 自动布局

ios - 处理两个应用程序 :openURL:sourceApplication:annotation

ios - 如何将两个branch.io深度链接与单个应用程序集成

ios - 快速更改占位符文本颜色

ios - 如何在同一个全局队列中添加后台任务?

ios - 如何在多个ViewController中使用locationManager()

ios - 在 swift4 中将 JSONresponse 转换为 NSDATA 或 NSDICTIONARY

ios - TMediaplayer 在文件播放前因 ARC 而被释放

objective-c - 通过dispatch_async block 传递可变参数