iPhoneで動作する映像フィルタをつくる:GPUImage+iOSのAVFoundationフレームワークその5〜クロマキー合成
こんにちは、andyです。
今回は、GPUImageを使ったクロマキー合成をしてみたいと思います。
ただ、まだちょっと試行錯誤段階で、動画同士の合成が思うように出来ていません。そのため、今回は申し訳ないのですが、バックグラウンドを静止画を使うということで許してください。
動画同士の合成がうまくいったらまたブログ更新します。
ソース
それではいつものようにソースコードから。
ヘッダーファイルはこんな感じ。
#import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> #import "GPUImage.h" @interface VideoFilterViewController : UIViewController - (IBAction)exportToMovie:(id)sender; //解説-1 - (IBAction)slider:(id)sender; @end
実装コードはこんな感じです。
#import "VideoFilterViewController.h" @interface VideoFilterViewController () { GPUImageMovie *movieFile; GPUImageView *filterView; GPUImageChromaKeyBlendFilter *filter; GPUImageMovieWriter* movieWriter; GPUImagePicture* picture; } @end @implementation VideoFilterViewController - (void)viewDidLoad { [super viewDidLoad]; [self showFilteringMovie]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)showFilteringMovie { [self makeChromakeyFilter]; [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector: @selector(play:) userInfo:nil repeats:NO]; } - (void)makeChromakeyFilter { if (filterView == nil) { filterView = [[GPUImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)]; } if (movieFile) { [movieFile cancelProcessing]; [movieFile removeAllTargets]; [picture removeAllTargets]; [filter removeAllTargets]; movieFile = nil; picture = nil; [filterView removeFromSuperview]; } //解説-2 NSURL *fileURL1 = [[NSBundle mainBundle] URLForResource:@"Explosion" withExtension:@"mp4"]; movieFile = [[GPUImageMovie alloc] initWithAsset:[AVURLAsset URLAssetWithURL:fileURL1 options:nil]]; UIImage* image = [UIImage imageNamed:@"<画像ファイル>"]; picture = [[GPUImagePicture alloc] initWithImage:image smoothlyScaleOutput:YES]; filter = [[GPUImageChromaKeyBlendFilter alloc] init]; //解説-3 [filter setColorToReplaceRed:0.0 green:0.0 blue:0.99]; [movieFile addTarget:filter]; [picture addTarget:filter]; [filter addTarget:filterView]; [self.view addSubview:filterView]; } - (void)play:(id)sender { __weak GPUImageMovie* weakMovieFile = movieFile; __weak GPUImagePicture* weakPicture = picture; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [weakPicture processImage]; [weakMovieFile startProcessing]; }); } - (void)exportStart:(id)sender { __weak GPUImageMovieWriter* weakMovieWriter = movieWriter; __weak GPUImageMovie* weakMovieFile = movieFile; __weak GPUImagePicture* weakPicture = picture; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [weakMovieWriter startRecording]; [weakPicture processImage]; [weakMovieFile startProcessing]; }); } - (IBAction)exportToMovie:(id)sender; { [self makeChromakeyFilter]; NSString* pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/tmp.mov"]; unlink([pathToMovie UTF8String]); NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie]; CGSize frame = CGSizeMake(640, 480); movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:frame fileType:AVFileTypeQuickTimeMovie outputSettings:nil]; [filter addTarget:movieWriter]; [movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter]; [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector: @selector(exportStart:) userInfo:nil repeats:NO]; } //解説-4 - (IBAction)slider:(id)sender { UISlider *slider = (UISlider *)sender; switch (slider.tag) { case 10: filter.smoothing = slider.value; break; case 11: filter.thresholdSensitivity = slider.value; break; } } @end
コード解説
解説-1
クロマキーフィルタのパラメータを動的に調整するために、Storyboardで予めスライダを2つ画面に追加しておき、スライダのコールバックを取得しています。
解説-2
前回とコードが変わっていますが、やってることはあまり変わりません。今回はクロマキーでキーイングを行うための動画1ファイルと、キーイングされた部分に表示するためのバックグラウンド画像を1ファイル用意しています。
解説-3
GPUImageChromaKeyBlendFilterというフィルタを使っていますが、この部分でキーイングされる部分のRGB値を設定しています。この値は0.0〜1.0までの値を与えるのですが、予めPhotoshopなどで動画のキーイングされる部分のカラー値を取得しておいて0〜255の値を0.0〜1.0に変換しました。
実際のプログラムでは、画面をタップしてその部分のカラー値をサンプリングすると良いと思います。
解説-4
スライダからのコールバックを受けています。タグ値10がキーイングする色の範囲、タグ値11がキーイングする色の明るさのしきい値です。調整して一番きれいにキーイングされる部分に設定します。
今回は、キーイングする動画の背景色データを入れなければならない関係で、キーイングに使う動画をアップさせていただきます。背景に使う画像は適当なものを使ってください。
動画のダウンロードはこちら。
今回はここまで。
次回はまだ何するか決めてません。
それではまた。
コメントをどうぞ