カメラアプリ開発入門(第3回)
画像加工のいろは
2013/7/27 名古屋iPhone開発者勉強会
基本的な画像加工について学ぶ
13年7月27日土曜日
大塚 崇(おおつか たかし)
DJ / フリーランスのエンジニア・プログラマ
ハンドル名: takatronix
Facebook/Twitter/Skype/LINE/Weibo -> takatronixhttp://takatronix.com趣味興味:旅行、語学、筋トレ、LEGO、FX、心理学、 脳科学、宇宙
自己紹介
13年7月27日土曜日
リリースしたアプリ
セクシーミラー、SEXY SCAN、 放射能汚染地図、和牛スキャン ...
(代表作)
セクシーミラー-編集不要の神自撮りアプリ
13年7月27日土曜日
http://sexymirror-app.com
2013/1リリース イギリスのiPhone総合で10位に、現在55万ダウンロード
セクシーミラー-編集不要の神自撮りアプリ
13年7月27日土曜日
画像加工の話の前に
Objective-Cのクラスを拡張する方法Category(カテゴリ)を覚えよう
13年7月27日土曜日
カテゴリって?
クラスを継承せずにクラスを拡張できる
Objective-Cの言語仕様
13年7月27日土曜日
クラス継承との比較メリット
デメリットメンバ変数の追加はできない
既存のクラスを拡張できる
13年7月27日土曜日
具体的なメリット画像加工のフィルタをViewControllerから
UIImageのメソッドに引越し
プロジェクトに依存しないため使い回しが楽 (゚д゚)ウマー
13年7月27日土曜日
カテゴリの文法をおぼよう
13年7月27日土曜日
クラス名+カテゴリ名.h
@interface クラス名 (カテゴリ名)-追加する関数宣言@end
クラス名+カテゴリ名.m
@implementation クラス名 (カテゴリ名)-追加する関数の実装@end
13年7月27日土曜日
UIImageを拡張する
13年7月27日土曜日
File->New->File...
13年7月27日土曜日
追加するクラスとカテゴリ名を設定
13年7月27日土曜日
タン、タンターンとひな形が完成
13年7月27日土曜日
http://takatronix.com/tutorial/20130525.zipカメラアプリ開発入門1プロジェクト
http://takatronix.com/tutorial/20130727.zip
今回のプロジェクト一式
13年7月27日土曜日
第一回目ので作成したフィルタをカテゴリに移動
13年7月27日土曜日
// モノクロフィルタ-(UIImage*)monochromeFilter:(UIImage*)image{ // UIImageをCoreImageに変換する CIImage* ciImage = [[CIImage alloc] initWithImage:image];
ViewControllerの関数から
// モノクロフィルタ-(UIImage*)monochromeFilter{ // UIImageをCoreImageに変換する CIImage* ciImage = [[CIImage alloc] initWithImage:self];
UIImage+Test.m
引数は必要なくself(自分の画像)をソースにする13年7月27日土曜日
UIimage+Test.h
@interface UIImage (Test)
// モノクロフィルタ-(UIImage*)monochromeFilter;// ケラレフィルタ(カメラの周辺光量落ち)-(UIImage*)vignetteFilter;
@end
13年7月27日土曜日
imageView.image = [self monochromeFilter:image];
imageView.image = [image monochromeFilter];
ViewControllerにフィルタがある場合(前回までの記述方法)
UIImageのカテゴリの場合
13年7月27日土曜日
_imageView.image = [[image monochromeFilter] vignetteFilter];
フィルタを重ねる
モノクロフィルタ -> ケラレ
13年7月27日土曜日
さてここから本題
13年7月27日土曜日
オフスクリーン描画とグラフィックスコンテキスト
を理解する
13年7月27日土曜日
オフスクリーン
画面に表示されていないメモリ上のスクリーン仮想画面とも言われる
13年7月27日土曜日
コンテキストとは
(英)Context :文の前後関係、文脈
ペンの色や背景色などを保存するリソース
グラフィックコンテキスト
13年7月27日土曜日
解像度を変更する
13年7月27日土曜日
UIImageに解像度変更機能を追加
-(UIImage*)resizedImage:(CGSize)size{
// 新しいサイズでオフスクリーンバッファを作成する UIGraphicsBeginImageContext(size); // 現在のコンテキスト(オフスクリーンバッファ)に 自分のイメージを描写する [self drawInRect:CGRectMake(0,0,size.width,size.height)]; // オフスクリーンバッファをUIImageに変換 UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); // オフスクリーンバッファを破棄 UIGraphicsEndImageContext(); // 新しい画像を返す return newImage ;}
13年7月27日土曜日
画像の切り出し
13年7月27日土曜日
UIImageに切り出し機能を追加
// 画像の一部分を切り出す-(UIImage*)cropImage:(CGRect)rect{
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect); UIImage *retImage = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); return retImage; }
13年7月27日土曜日
画像の反転
13年7月27日土曜日
UIImageに画像反転機能を追加する
- (UIImage *)mirrorImage{ CGImageRef imgRef = [self CGImage]; // 画像データ取得 UIGraphicsBeginImageContext(self.size);
// コンテキスト取得 CGContextRef context = UIGraphicsGetCurrentContext();
// コンテキストの軸をXもYも等倍で反転 CGContextTranslateCTM( context, self.size.width, self.size.height); // コンテキストの原点変更 CGContextScaleCTM( context, -1.0, -1.0); // コンテキストにイメージを描画 CGContextDrawImage( context, CGRectMake( 0, 0, self.size.width, self.size.height), imgRef); // コンテキストからイメージを取得 UIImage *retImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return retImg;}
13年7月27日土曜日
座標系の話
CoreGraphicsは左下基準Y軸が反転している
13年7月27日土曜日
CTMとは変換行列(CTM : Current Transformation Matrix)
13年7月27日土曜日
画像の回転
13年7月27日土曜日
画像の回転-(UIImage*)rotateImage:(int)angle{ CGImageRef imgRef = [self CGImage]; CGContextRef context; // 角度に応じて現在のコンテキストのCTMを変更 switch (angle) { case 90: UIGraphicsBeginImageContext(CGSizeMake(self.size.height, self.size.width)); context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, self.size.height, self.size.width); CGContextScaleCTM(context, 1.0, -1.0); CGContextRotateCTM(context, M_PI/2.0); break; case 180: UIGraphicsBeginImageContext(CGSizeMake(self.size.width, self.size.height)); context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, self.size.width, 0); CGContextScaleCTM(context, 1.0, -1.0); CGContextRotateCTM(context, -M_PI); break; case 270: UIGraphicsBeginImageContext(CGSizeMake(self.size.height, self.size.width)); context = UIGraphicsGetCurrentContext(); CGContextScaleCTM(context, 1.0, -1.0); CGContextRotateCTM(context, -M_PI/2.0); break; default: return self;
} // オフスクリーンに描写->UIImage変換 CGContextDrawImage(context, CGRectMake(0, 0, self.size.width, self.size.height), imgRef); UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return retImage;}
13年7月27日土曜日
プロジェクトとこのスライドはここから落とせますよ。
http://takatronix.com/tutorial/20130727.zip
13年7月27日土曜日
ありがとうございました
takatronix 検索
http://takatronix.com13年7月27日土曜日