iOS 中与拍照并发的图像处理任务
Concurrent image processing task with photo taking in iOS
我需要你在 swift 中的 GCD 帮助,我刚开始使用这个工具,我有点困惑。假设我有一个函数 foo() 可以拍照并将其保存到 var,在这个函数中还有另一个函数可以检查照片上是否有人脸并返回 true 或 false。接下来,当用户点击 usePhotoFromPreview 按钮时,只要照片上没有人脸,它就会通过自定义委托保存照片,如下所示:
var image: UIImage?
var checkingPhotoForFaces: Bool?
func foo(){
let videoConnection = imageOutput?.connection(withMediaType: AVMediaTypeVideo)
imageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (imageDataSampleBuffer, error) -> Void in
if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) {
image = UIImage(data: imageData)
self.checkingPhotoForFaces = self.detect(image: image)
}
})
}
func detect(image: UIImage) -> Bool{
.....
}
func usePhotoFromPreview(){
self.dismiss(animated: true, completion: {
if self.checkingPhotoForFaces == false{
self.delegate?.takenPhoto(photo: self.image!)
print("photo taken")
}else{
self.delegate?.takenPhoto(photo: nil)
print("no photo taken")
}
})
}
所以现在是棘手的部分,我想让检测函数异步执行,并且只有在完成后才执行 usePhotoFromPreview。由于 CoreImage 的实现,我想 detect func 应该在主线程上。我只是做了这样的事情:
func foo(){
...
DispatchQueue.global().async {
self.checkingPhotoForFaces = self.detect(image: stillImage)
}
...
}
但问题是当用户在该按钮上点击得太快时它不起作用,因为检测功能仍在处理中,所以我想我需要某种队列,但我不知道是哪一个。
顺便说一句。请不要坚持上面缺少一些参数,我正在写它,这不是重点
感谢您的帮助
如上评论更改检测:
func detect(image: UIImage, completion: ()->(detectedFaces: Bool)){
//.....
completion(true|false)
}
然后
if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) {
image = UIImage(data: imageData)
self.detect(image) { detectedFaces in
self.checkingPhotoForFaces = detectedFaces
//Enable button?
}
}
我需要你在 swift 中的 GCD 帮助,我刚开始使用这个工具,我有点困惑。假设我有一个函数 foo() 可以拍照并将其保存到 var,在这个函数中还有另一个函数可以检查照片上是否有人脸并返回 true 或 false。接下来,当用户点击 usePhotoFromPreview 按钮时,只要照片上没有人脸,它就会通过自定义委托保存照片,如下所示:
var image: UIImage?
var checkingPhotoForFaces: Bool?
func foo(){
let videoConnection = imageOutput?.connection(withMediaType: AVMediaTypeVideo)
imageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (imageDataSampleBuffer, error) -> Void in
if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) {
image = UIImage(data: imageData)
self.checkingPhotoForFaces = self.detect(image: image)
}
})
}
func detect(image: UIImage) -> Bool{
.....
}
func usePhotoFromPreview(){
self.dismiss(animated: true, completion: {
if self.checkingPhotoForFaces == false{
self.delegate?.takenPhoto(photo: self.image!)
print("photo taken")
}else{
self.delegate?.takenPhoto(photo: nil)
print("no photo taken")
}
})
}
所以现在是棘手的部分,我想让检测函数异步执行,并且只有在完成后才执行 usePhotoFromPreview。由于 CoreImage 的实现,我想 detect func 应该在主线程上。我只是做了这样的事情:
func foo(){
...
DispatchQueue.global().async {
self.checkingPhotoForFaces = self.detect(image: stillImage)
}
...
}
但问题是当用户在该按钮上点击得太快时它不起作用,因为检测功能仍在处理中,所以我想我需要某种队列,但我不知道是哪一个。
顺便说一句。请不要坚持上面缺少一些参数,我正在写它,这不是重点
感谢您的帮助
如上评论更改检测:
func detect(image: UIImage, completion: ()->(detectedFaces: Bool)){
//.....
completion(true|false)
}
然后
if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) {
image = UIImage(data: imageData)
self.detect(image) { detectedFaces in
self.checkingPhotoForFaces = detectedFaces
//Enable button?
}
}