問題
まず毎フレームごとに何か処理したい場合は
処理したい画像を出力するGPUImageFilterのframeProcessingCompletionBlock
に処理を設定する。
しかし単純にimageFromCurrentFramebuffer
を呼び出しても上手くイメージを取得できない。対応策がわかったので記録を残す
対応
問題はgithubのissueにあるように
frameProcessingCompletionBlock
処理内でuseNextFrameForImageCapture
が呼ばれることを設計者が想定していなかったことの模様。
frameProcessingCompletionBlock
が呼び出された時点でこちらが必要としているframeがすでにfilterを通過済みのため、frameProcessingCompletionBlock
内でuseNextFrameForImageCapture
を呼び出しても次のフレーム用となる。
事前にframeProcessingCompletionBlock
処理呼び出し前に
useNextFrameForImageCapture
を呼び出したら上手く行った
import UIKit
import GPUImage
class ViewController: UIViewController {
@IBOutlet weak var outputView: GPUImageView!
@IBOutlet weak var copyImageView: UIImageView!
var videoCamera:GPUImageVideoCamera?
var grayScalefilter:GPUImageGrayscaleFilter?
override func viewDidLoad() {
super.viewDidLoad()
self.videoCamera = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPreset352x288, cameraPosition: .Back)
self.videoCamera?.outputImageOrientation = .Portrait
self.grayScalefilter = GPUImageGrayscaleFilter()
videoCamera?.addTarget(grayScalefilter)
let lastFilter = grayScalefilter
lastFilter?.addTarget(outputView)
lastFilter?.frameProcessingCompletionBlock = { (output,t) in
//次回frameProcessingCompletionBlockが呼び出された時のための対処
defer { output!.useNextFrameForImageCapture() }
//uiimageの取得
guard let image = output!.imageFromCurrentFramebuffer() else {
print("error get image!")
return
}
//mainスレッドで処理する
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.copyImageView.image = image
})
}
//最初のフレーム用の呼び出し
lastFilter?.useNextFrameForImageCapture()
videoCamera?.startCameraCapture()
}
}