Mac初心者のiPhoneアプリ開発記6 画像処理はじめました

1前回から随分時間が経ってしまいました。iPhoneアプリ市場は激戦なので、果たして結果に繋がるか考えるとモチベが下がりがち。

しかし今回はようやくXcodeにも慣れ始め、少しづつ楽しくなってきました。

今回は教材を何にするか迷いました。そろそろ自分が作りたいアプリの種類(ゲームやツール等)により勉強内容が変わってきます。私はとりあえず「iPhone Screenshot Maker」のiPhoneアプリを開発しようと考えているので、画像処理の勉強をすることにしました。

そこで今回は先日話題になっていた「蜷川実花監修カメラアプリcameranのエンジニアが教える高速フィルターカメラアプリの作り方」のレジュメを公開します – kasajei(以下、教材)に沿って勉強したいと思います。

丁寧な解説のおかげでまだまだ初心者の私にもスムースに進める事ができました

 

何をするの?

iPhoneで画像の合成や色調変換などの画像処理を行います。画像処理の為に”GPUImage”というライブラリを使います。GPUImageは標準ではないので、ライブラリをプロジェクトに追加する方法から勉強します。教材では下のように色調変換や合成をします。

2

今回はさらに下の改造を行なってみました。改造には8時間くらいかかりました。(;・∀・)

  1. 写真アルバムから画像を選択できるようにする。
  2. iPhoneフレーム以外にゲームボーイを追加する。

まずは教材に沿って進めます。

 

初心者でもちゃんと作れる

教材は非常に丁寧に出来ており、しっかり読んでいけば迷うことはない。Xcodeを数回使ったレベルの人でも大丈夫。いま何をやっているのかをしっかり意識して進めたい。教材の流れは、

1. プロジェクト作成&GPUImageの組み込み

プロジェクト作成後にフレームワークにGPUImageを追加してパスを通す。次にGPUImageに必要なフレームワークをいくつか追加して、ビルドが通るかを確認。これでGPUImageを使うための土台ができる。

2. GPUImageを動かしてみる

3さっそくGUIを作る。スクリーンショットが載っているので迷うことはない。Autosizingを触らないとボタンが表示されなかった。

command + option + returnでコードを表示してGUIと紐付けするのは面白い!

しかし私はここで間違えて、ボタンのConnectionをActionにするべきところをOutletのままで紐付けしてしまった。間違いに気付いてコードを削除しても、どうやら紐付け情報はコード以外にも残っているようでコンパイルエラーから抜け出せなくなった。

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<ViewController 0xa824610> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key pressFilterBtn.'

結局、紐付けの完全な削除方法は分からず、最終的にプロジェクトを作りなおした。この問題とはいずれ向き合う必要がある。

次はフィルターを作って画像処理に入る。ここまでで教材の半分くらい。

3. フィルターを作ってみる

セピアフィルターに始まり、順を追って画像の縮小や合成を行なっていく。ここはソースのコメントを見ていけば何をしているか把握できると思う。GDやImageMagickに慣れていると、なんとも面倒な手続きが萌える。

最後にセーブ処理を実装して教材は終わり。画像処理は結果が派手なので感動すると思う。GUIの紐付けとGPUImageの画像処理は、Xcodeの醍醐味ともいえる体験。

 

写真アルバムから画像を選択できるようしたい

ここまではコピペでも達成感が得られますが、改造となるとハードルが上がります。 最終的に私は「iPhone Screenshot Maker」を作るのが目的なので、画像を選択できることは必須です。

とりあえず画像の取得方法についてググると、UIImagePickerControllerクラスで画像選択が出来ることが分かる。

イメージの取得と保存 - 分からないことをひたすらメモするブログ。

流れとしては、

  1. 新たに画像選択画面を表示するボタンを作成
  2. ボタンが押されたら画像選択画面表示
  3. 画像が選択されたらimageViewに反映

教材で作ったボタンと同じように新しいボタンを作成&紐付けする。名前はpressLoadImageBtnとした。action内の処理と、画像選択後の処理は下のようになった。

ViewController.m
- (IBAction)pressLoadImageBtn:(id)sender {
    // インタフェース使用可能なら
    if ( [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] ) {
        // UIImageControllerの初期化
        UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
        /* UIImageControllerで取得できるデータは以下の3つ
         * SourceTypeCamera                : カメラを起動する
         * SourceTypePhotoLibrary        : フォトライブラリーを開く
         * SourceTypeSavedPhotosAlbum    : (カメラがあるiPhoneは)カメラロールから選択する
         */
        [ipc setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
        // Delegateセット
        [ipc setDelegate:self];
        // NOを設定するとイメージを取得できない
        [ipc setAllowsEditing:YES];
        // 指定したViewを一番上に表示する
        [self presentViewController:ipc  animated:YES completion: nil];
    }
}

//イメージ取得後に呼び出される関数
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    // 選択したイメージをimageにセットする
    UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
    // imageをImageViewerにセットする
    [self.imageView setImage:image];
    [self dismissViewControllerAnimated:YES completion:NULL];
}

UIImagePickerControllerのデリゲートには、UIImagePickerControllerDelegateとUINavigationControllerDelegateをヘッダファイルに記述する必要がある。

ViewController.h
@interface ViewController : UIViewController
<UINavigationControllerDelegate,UIImagePickerControllerDelegate> {
}

@property (weak, nonatomic) IBOutlet UIImageView *imageView;
- (IBAction)pressFilterBtn:(id)sender;
- (IBAction)pressSaveBtn:(id)sender;
- (IBAction)pressLoadImageBtn:(id)sender;
@end

4以上で画像を選択できるようになった!

※iOSシミュレーターの画像アルバムにテスト用の画像を入れるには、シミュレーターに画像をドラッグすればiOS内のSafariで画像が開くので、それを左クリック長押しで保存できる。

うたブログ〜情報編: iOSシミュレーター上のアルバムに画像を入れる方法

 

iPhoneフレーム以外にゲームボーイを追加する

次はiPhoneフレームに加え定番のゲームボーイを追加してみます。

まずはまた新しくボタンを作ります。名前はpressGBBtnとした。次にresourceにgb.pngを追加。教材を参考にしつつgb.pngとの合成処理を作成します。

gb.png

gb.png

GBの液晶画面がセピア色ではちょっと変なので、代わりにモノクロフィルターを使用しました。GPUImageのマニュアルにGPUImageMonochromeFilterの使用方法が載っています。

BradLarson/GPUImage · GitHub

ViewController.m
- (IBAction)pressGBBtn:(id)sender {
    // GUIで設定した画像を取得する
    UIImage *inputImage = self.imageView.image;
    GPUImagePicture *targetImage = [[GPUImagePicture alloc] initWithImage:inputImage];

    // セピアフィルターの代わりにGPUImageMonochromeFilterを使用
    GPUImageMonochromeFilter *colorFilter = [[GPUImageMonochromeFilter alloc] init];
    [(GPUImageMonochromeFilter *)colorFilter setColor:(GPUVector4){0.3f, 0.4f, 0.0f, 0.2f}];
    [targetImage addTarget:colorFilter];

    // GBの画像を用意する
    UIImage *gb = [UIImage imageNamed:@"gb.png"];
    GPUImagePicture *gbImg = [[GPUImagePicture alloc] initWithImage:gb];

    // 画像を合成するためのブレンドモードを作る
    GPUImageNormalBlendFilter *nomalBlend = [[GPUImageNormalBlendFilter alloc] init];

    // GBの画像変形のためフィルターを作る
    GPUImageTransformFilter *transform = [[GPUImageTransformFilter alloc] init];
    CGAffineTransform trans;
    trans = CGAffineTransformMakeScale(0.31, 0.28); // 縮小
    trans = CGAffineTransformTranslate(trans, 0, -1.6); // 移動
    [transform setAffineTransform:trans];

    // 変形する
    [colorFilter addTarget:transform];

    // ブレンドする
    [gbImg addTarget:nomalBlend];
    [transform addTarget:nomalBlend atTextureLocation:1];

    // フィルター実行
    [gbImg processImage];
    [targetImage processImage];

    // 実行したフィルターから画像を取得
    UIImage *outputImage = [nomalBlend imageFromCurrentlyProcessedOutput];

    // 取得した画像をセット
    self.imageView.image = outputImage;
}

やや荒削りですが、ゲームボーイらしくなりました。

1

今回はGPUImageという外部ライブラリによって画像処理の土台を築くことが出来ました。しかし画像サイズは表示領域の制限を受けたままだし、iPhoneのアスペクト比も調整が必要そう。さらにアフィン変換ではないピクセル単位の変形など分からないことは山積み。今後はGPUImageで何が可能か、後は他の画像ライブラリについてもリサーチする必要がありそうです。

 

この連載の一覧

  1. Mac初心者のiPhoneアプリ開発記

    この記事は先日購入したMacBook Air(略してMBA)でiPhoneアプリ...

  2. Mac初心者のiPhoneアプリ開発記2 Xcodeの闇の中で

    iPhoneアプリ開発するぞ!と意気込んでMBAを購入したのは1年前。でもAnd...

  3. Mac初心者のiPhoneアプリ開発記3 Objective-Cの壁

    手探りで進めているiPhoneアプリ開発記。前回は@ITの記事を参考に、Xcod...

  4. Mac初心者のiPhoneアプリ開発記4 Objective-Cの復讐

    前回から10日もたってしまい、ほとんど忘れてる状態からの再開です。今回も引き続き...

  5. Mac初心者のiPhoneアプリ開発記5 因縁のTwitterビューア

    今回は難しくて挫折していた「iOS 4のSDKで、Twitterを使ったiPho...

  6. Mac初心者のiPhoneアプリ開発記6 画像処理はじめました

    前回から随分時間が経ってしまいました。iPhoneアプリ市場は激戦なので、果たし...

  7. Mac初心者のiPhoneアプリ開発記7 設定画面を作る

    今回はツール系アプリなら装備しておきたい、いわゆる設定画面を作ります。今後アプリ...

  8. iOSの進化とフラットデザイン

    iKuracさんが作成したiOSの比較画像。先日発表されたiOS7のデザインの路...

  9. Mac初心者のiPhoneアプリ開発記8 設定画面を動的に作る

    前回は設定画面を作るためにストーリーボードやTableViewの仕組みを勉強しま...

  10. Mac初心者のiPhoneアプリ開発記9 アプリ申請までの道

    ようやく!初のiPhoneアプリ申請までたどり着きました。名前は『Screens...

  11. Mac初心者のiPhoneアプリ開発記 リリース後の反応

    実は先日8/9に『Screenshot Maker Pro』がリリースしました。...

  12. 大人センスなiPhone壁紙『A new world』

    NYで活躍中のドイツ人デザイナーTobias van Schneiderさんの作...

  13. ReynoldsさんのiPhone壁紙

    渋い色調のポリゴン地形がお洒落。Timothy J. Reynoldsさんの作品...

  14. シンプルの美学アンソニーさんのiPhone壁紙

    Anthony Zinonosさんの壁紙。青と黒、シンプルに色分けされた海上にオ...

  15. iPhoneアプリ開発記 iOS7対応で必要だったこと

    公開中のiPhoneアプリ『Screenshot Maker Pro』をiOS7...

  16. Cocos2d-xでiPhone&Androidアプリ開発記1

    そろそろ次のアプリ開発と日々考えていたんですが、私は個人開発なので今後は小粒なゲ...

  17. Cocos2d-xでiPhone&Androidアプリ開発記2 バージョン3.x系挫折

    『ドラゴンクエストモンスターズ スーパーライト』がCocos2d-xで開発とのこ...

  18. Cocos2d-xでiPhone&Androidアプリ開発記3 初心者TIPS

    今回で3回目のCocos2d-x連載。自作アプリを製作中ですが7割ほど完成してき...

  19. Cocos2d-xでiPhone&Androidアプリ開発記4 AdMobメディエーションでAdMob+iAd iOS編

    Cocos2dxで広告を表示するにはiOSとAndroid別々に設定が必要です。...

  20. Cocos2d-xでiPhone&Androidアプリ開発記5 AdMob Android編

    iOSに続きAndroidにAdmodを導入します。とりあえずAdModだけ表示...

  21. Cocos2d-xでiPhone&Androidアプリ開発記6 Android対応

    Androidアプリ開発経験は全くない状態で始めたCocos2dx。ここまでの開...

  22. Cocos2d-xでiPhone&Androidアプリ開発記7 ローカライズとアイコン組み込み

    ようやく初めてのcocos2dxアプリが完成しました! アルファベットを組み合わ...

  23. Cocos2d-xでiPhone&Androidアプリ開発記8 開発の流れとアプリ申請

    Cocos2d-xで初めてのアプリを公開しました。AndroidとiPhone両...

  24. Cocos2d-xでiPhone&Androidアプリ開発記9 SQLiteの注意点

    Cocos2d-xからSQLiteを使うには、iOSとAndroidそれぞれにラ...

  25. Cocos2d-xでiPhone&Androidアプリ開発記10 アプリ高速化

    Cocos2d-xで2本目をリリースしました。前回の英語パズルの続編『英単語ギズ...

  26. Cocos2d-xでiPhone&Androidアプリ開発記11 Androidのデバッグ

    Cocos2d-xによるアプリの新作をほぼ作り終えました。開発はXCode主体で...

  27. iOS/Androidアプリ『英単語RPG ワード・オブ・ザ・リング』

    iPhone/Androidアプリ『英単語RPG ワード・オブ・ザ・リング』を公...

  28. 人にも読めるQRコード

    人にも読めるQRコード『Human Readable Quick Respons...

  29. Xcode7にiOS 8 Simulatorがインストールできない

    Xcode 7.0.1に、iOS 8.1 Simulatorをインストールしよう...

 

 

広告