LoginSignup
23
26

More than 5 years have passed since last update.

GPUImageでカメラアプリ作成をはじめて1時間経過。やはりハマる

Last updated at Posted at 2014-06-07

フィルタ処理された画像を取り出すのにハマる

よーしまずは画像をセピア色にしよう!と思って、チュートリアル的なサイトを探して参考にさせていただいた。
「蜷川実花監修カメラアプリcameranのエンジニアが教える高速フィルターカメラアプリの作り方」のレジュメを公開します
その他いくつかのサイトでもここを参考に、類似の実装を行っているようだし、はじめの一歩なのでさすがに簡単そうに見えた。

さくさくと進めるかと思いきや、imageFromCurrentlyProcessedOutputセレクタが見つからず、???となってしまった。

そこで、githubのページをきちんと読み直したら解決策を見つけた。

UIImage *inputImage = [UIImage imageNamed:@"Lambeau.jpg"];

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage];
GPUImageSepiaFilter *stillImageFilter = [[GPUImageSepiaFilter alloc] init];

[stillImageSource addTarget:stillImageFilter];
[stillImageFilter useNextFrameForImageCapture] //imageFromCurrentlyProcessedOutputを使うならその前にこれを呼び出す
[stillImageSource processImage];

UIImage *currentFilteredVideoFrame = [stillImageFilter imageFromCurrentFramebuffer]; //以前はimageFromCurrentlyProcessedOutput

githubのissuesや、本家サイトを確認してみると、

  • フレームワークのメモリ利用量の削減
  • メモリ関連のクラッシュ回避

などの観点から変更した模様。
この件、日本語の情報はまだ少ないな・・。

GPUImageView は UIImageViewではない?でハマる

次に、githubのサンプルを活用してみようと、SimpleImageFilterを弄ってみることにした。
サンプルはloadViewでGPUImageViewを初期化しているが、自分はstroyboardでUIImageViewを使ってプレースホルダ画像を活用したいと思っている。
しかし、下記の実装だと実行時エラーが出てしまう。

    /***
      ここで登場するself.imageViewはstoryboardにて接続したUIImageViewのこと。
     実装は、UIViewControllerのviewDidLoad内の処理。
    ***/

    //GUIで設定した画像を取得する
    UIImage *inputImage = nil;
    inputImage = self.imageView.image;

    //画像をGPUImageのフォーマットに変換する
    GPUImagePicture *sourcePicture;
    sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage smoothlyScaleOutput:YES];

    //セピアフィルターを作る
    GPUImageSepiaFilter *sepiaFilter = [[GPUImageSepiaFilter alloc] init];
    GPUImageView *theImageView = (GPUImageView *)self.imageView; //キャストしてるんだけど・・。
    [self.sepiaFilter forceProcessingAtSize:theImageView.sizeInPixels];

    //ターゲット設定する
    [sourcePicture addTarget:sepiaFilter];
    [self.sepiaFilter addTarget:theImageView]

    //フィルターを実行
    [sourcePicture processImage];

エラーログの一部はこのような感じで、キャストしているんだけどGPUImageVIewのアクセサメソッドが認識されないようだ。ログを見れば[UIImageView sizeInPixels]とあり、確かにこの文字列だけ見たら通らないな、とは思うのだけど・・。

-[UIImageView sizeInPixels]: unrecognized selector sent to instance ...

直接関係ないが、 http://stackoverflow.com/a/23747248 にライブラリ作者様のコメントがある。

GPUImageView is not a subclass of UIImageView.

今回の件は、サブクラスではないけど一応ダウンキャスト(サブクラスへのキャスト)としてコンパイルできるものの、結局は定義していないメソッドの実行箇所で落ちる、ということだろうか。
そもそもダウンキャスト自体が危険なアプローチになることが多いらしいので注意が必要だ。
カメラアプリの開発を進める中で、もう少し深堀できると良い。

23
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
26