カメラアプリ開発入門
(第一回
)
まずは基本の基本から
CoreImageを使った画像加工まで
2013/5/25 名古屋iPhone開発者勉強会
大塚 崇(おおつか たかし)
DJ / フリーランスのエンジニア・プログラマ
ハンドル名
:
takatronix
Facebook/Twitter/Skype/LINE/Weibo ->
takatronix
http://takatronix.com
趣味興味:
旅行、語学、筋トレ、
LEGO、FX、心理学、
脳科学、宇宙
自己紹介
リリースしたアプリ
デカ目ミラー、
SEXY SCAN、 放射能汚染地
図、和牛スキャン
...
デカ目ミラー(SexyMirror)2013/1リリース
イギリスの
iPhone総合で何故か10位に、
現在40万ダウンロード
iOSカメラAPI
UIImagePickerController
AVFoundation.framework
iOS4から、標準のカメラUIを使わない
アプリが作れる
よくあるカメラの
UI
非常に簡単だが自由がない
リアルタイムエフェクトはできない
実装は結構大変だがなんでもできる
iOS画像処理方法
CoreImage (CPU/GPU)
OpenGL (GPU)
ピクセル処理
(CPU)
OpenCV (CPU/GPU)
vImage (GPU)
UIImagePickerController
の使い方
ViewController.h に追加
#import <UIKit/UIKit.h>ViewController.hに追加
#import
<UIKit/UIKit.h>
@interface
ViewController :
UIViewController
<
UIImagePickerControllerDelegate
,
UINavigationControllerDelegate
>
@property
IBOutlet
UIImageView
* imageView;
フォトライブラリを開く処理
ViewController.mに追加
// フォトライブラリを開く
- (IBAction)openPhotoLibrary:(id)sender {
// フォトライブラリが使えるかチェック
// カメラを開く場合
// UIImagePickerControllerSourceTypePhotoLibrary を
// UIImagePickerControllerSourceTypeCamera に変更
! if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) ! {
// UIImagePickerControllerを作成し初期化 new = alloc + init
! ! UIImagePickerController* imagePicker = [UIImagePickerController new]; // カメラを開く場合 sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; // 編集可能にする場合はYES
imagePicker.allowsEditing = YES; // 自分への通知設定
imagePicker.delegate = self;
// フォトライブラリを開く
[self presentViewController:imagePicker animated:YES
completion:^{ // 開いたタイミングに呼ばれる NSLog(@"(1)フォトライブラリを開いた"); }]; } }
ViewController.mに追加
撮影後
orサムネイル選択後に呼ばれる処理
テキスト
// 写真撮影後orサムネイル選択後に呼ばれる処理-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
! // オリジナル画像
! UIImage* originalImage = (UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage]; ! // 編集画像
! UIImage* editedImage = (UIImage *)[info objectForKey:UIImagePickerControllerEditedImage]; UIImage* savedImage; if(editedImage){ savedImage = editedImage; } else{ savedImage = originalImage; } // 選択された画像を表示
_imageView.image = savedImage;
// 開いているカメラ・フォトライブラリを閉じる
[self dismissViewControllerAnimated:YES completion:^{
}]; }
シミュレータに画像がない場合
フィルタがないカメラアプリ
とか小学生までだよねー?
ViewController.mに追加
#import
"ViewController.h"
#import
<CoreImage/CoreImage.h>
@interface
ViewController ()
モノクロフィルタを作る
ViewController.mに追加
// グレースケール画像を作成する
-(UIImage*)monochromeFilter:(UIImage*)image{
// UIImageをCoreImageに変換する
CIImage* ciImage = [[CIImage alloc] initWithImage:image];
// CoreImageフィルタを作成する
CIFilter* ciFilter = [CIFilter filterWithName:@"CIColorMonochrome"
keysAndValues:kCIInputImageKey, ciImage, // パラメータ:入力色(RGBのフィルタ係数)
// セピア色にするなら [CIColor colorWithRed:1.0 green:0.7 blue:0.4]
@"inputColor", [CIColor colorWithRed:1.0 green:1.0 blue:1.0], // パラメータ(度合い)
// 0.5にすれば半分の適用度になります
@"inputIntensity", [NSNumber numberWithFloat:1.0], nil];
// CoreImageのコンテクストを作成
CIContext* ciContext = [CIContext contextWithOptions:nil]; // フィルタを適用
CGImageRef cgImage = [ciContext createCGImage:ciFilter.outputImage fromRect:[ciFilter.outputImage extent]]; // CGImageRefをUIImageに変換
UIImage* retImage = [UIImage imageWithCGImage:cgImage scale:image.scale orientation:UIImageOrientationUp]; // CGImage開放
フィルタを適用する
ViewController.mを修正
// 写真撮影後orサムネイル選択後に呼ばれる処理
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary
*)info {
! // オリジナル画像
! UIImage* originalImage = (UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage]; ! // 編集画像
! UIImage* editedImage = (UIImage *)[info objectForKey:UIImagePickerControllerEditedImage]; UIImage* savedImage; if(editedImage){ savedImage = editedImage; } else{ savedImage = originalImage; } // モノクロフィルタを適用してから // 選択された画像を表示
_imageView.image = [self monochromeFilter:savedImage]; // 開いているカメラ・フォトライブラリを閉じる
[self dismissViewControllerAnimated:YES completion:^{
}]; }
パラメータを変えてみよう
@"inputColor", [CIColor colorWithRed:1.0 green:0.7 blue:0.4],
@"inputColor", [CIColor colorWithRed:1.0 green:1 blue:0],
ケラレフィルタ(カメラの周辺光量落ち)
ケラレフィルタを作る
// ケラレフィルタ(カメラの周辺光量落ち)-(UIImage*)vignetteFilter:(UIImage*) image{
// UIImageをCoreImageに変換する
CIImage* ciImage = [[CIImage alloc] initWithImage:image];
// CoreImageフィルタを作成する
CIFilter* ciFilter = [CIFilter filterWithName:@"CIVignette"
keysAndValues:kCIInputImageKey, ciImage, //
@"inputRadius", [NSNumber numberWithFloat:2.0], // パラメータ(度合い)
// 0.5にすれば半分の適用度になります
@"inputIntensity", [NSNumber numberWithFloat:1.0], nil];
// CoreImageのコンテクストを作成
CIContext* ciContext = [CIContext contextWithOptions:nil]; // フィルタを適用
CGImageRef cgImage = [ciContext createCGImage:ciFilter.outputImage fromRect:[ciFilter.outputImage extent]]; // CGImageRefをUIImageに変換
UIImage* retImage = [UIImage imageWithCGImage:cgImage scale:image.scale orientation:UIImageOrientationUp]; // CGImage開放
CGImageRelease(cgImage);
// 写真撮影後orサムネイル選択後に呼ばれる処理
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
! // オリジナル画像
! UIImage* originalImage = (UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage]; ! // 編集画像
! UIImage* editedImage = (UIImage *)[info objectForKey:UIImagePickerControllerEditedImage]; UIImage* savedImage; if(editedImage){ savedImage = editedImage; } else{ savedImage = originalImage; } // モノクロフィルタ+ケラレフィルタを適用し、画面に表示
_imageView.image = [self vignetteFilter:[self monochromeFilter:savedImage]]; // 開いているカメラ・フォトライブラリを閉じる
[self dismissViewControllerAnimated:YES completion:^{
}]; }
カメラロールへ保存
-(void)image:(UIImage*)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo{ if(error){ NSLog(@"Error"); }else{ NSLog(@"保存した"); } }
ViewController.mへ追加
// 写真撮影後orサムネイル選択後に呼ばれる処理-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
! // オリジナル画像
! UIImage* originalImage = (UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage]; ! // 編集画像
! UIImage* editedImage = (UIImage *)[info objectForKey:UIImagePickerControllerEditedImage]; UIImage* savedImage; if(editedImage){ savedImage = editedImage; } else{ savedImage = originalImage; } // モノクロフィルタ+ケラレフィルタを適用し、画面に表示
_imageView.image = [self vignetteFilter:[self monochromeFilter:savedImage]]; // カメラロールへ保存する
UIImageWriteToSavedPhotosAlbum(_imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
// 開いているカメラ・フォトライブラリを閉じる
[self dismissViewControllerAnimated:YES completion:^{
}]; }