しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

GPUImageでカメラの画像にリアルタイムでフィルターをかける

GPUImageというライブラリを使って、カメラ映像にリアルタイムでフィルターをかける事を試してみました。

github.com

まずはCocoaPodsでGPUImageをインストールします。

target 'MyApp' do
  use_frameworks!

  pod 'GPUImage'
end

次はInfo.plistのNSCameraUsageDescriptionキーに、カメラ使用理由を追加します。

f:id:llcc:20170927144842p:plain

続けて画面にカメラの映像を表示してみます。
適当なViewControllerを以下のように修正します。

import UIKit
import GPUImage

class ViewController: UIViewController {
    let camera = GPUImageVideoCamera(sessionPreset: AVCaptureSession.Preset.vga640x480.rawValue, cameraPosition: .back)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        camera?.outputImageOrientation = .portrait
        let imageView = GPUImageView(frame: view.bounds)
        view.addSubview(imageView)
        
        camera?.addTarget(imageView)
        camera?.startCapture()
    }
}

f:id:llcc:20170927145102p:plain

カメラの映像を撮っているのはGPUImageVideoCameraというクラスです。
このクラスは画面サイズやどのカメラを使うかなどの情報を渡して初期化します。

let camera = GPUImageVideoCamera(sessionPreset: AVCaptureSession.Preset.vga640x480.rawValue, cameraPosition: .back)

カメラの映像を画面に表示しているのが下の処理です。
GPUImageViewというビューを画面に貼り付け、それをカメラに紐付ける事で、カメラ映像を画面に表示しています。

let imageView = GPUImageView(frame: view.bounds)
view.addSubview(imageView)
camera?.addTarget(imageView)

続けて映像にリアルタイムフィルターを適用してみます。
先程の処理を下のように置き換えます。

class ViewController: UIViewController {
    let camera = GPUImageVideoCamera(sessionPreset: AVCaptureSession.Preset.vga640x480.rawValue, cameraPosition: .back)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        camera?.outputImageOrientation = .portrait
        let imageView = GPUImageView(frame: view.bounds)
        view.addSubview(imageView)
        
        let filter = GPUImageiOSBlurFilter()
        camera?.addTarget(filter)
        filter.addTarget(imageView)
        camera?.startCapture()
    }
}

今回の修正箇所は下の部分です。
フィルタークラス(GPUImageiOSBlurFilter)を生成して、それをカメラとImageViewと紐付けています。

let filter = GPUImageiOSBlurFilter()
camera?.addTarget(filter)
filter.addTarget(imageView)

下が実行時の映像です。
分かりにくいのですが、カメラ映像にぼかし処理がかかっています。

f:id:llcc:20170927150100g:plain