前回はカメラを使って写真を撮るところまで説明した。今回は、この写真を表示するところから始めよう。
UIImageとUIImageView
UIImagePickerControllerを使った写真の撮影が終了すると、デリゲートメソッドであるimagePickerController:didFinishPickingImage:editingInfo:が、呼び出される。このメソッドの第二引数として、UIImageというクラスのオブジェクトが渡ってくる。これが、撮影した写真を表すクラスになる。
ただし、この第二引数として渡されてくるUIImageは、写真撮影後にクロップなどの編集が行われた後のデータであることに注意してほしい。つまり、撮影時に画面に映っていた画像そのものになるが、実際に撮影されたオリジナルのデータではない。画像サイズも、320 x 320とスクリーンサイズにあったものになっている。
では、オリジナルデータにはどうやってアクセスするかというと、第三の引数であるeditingInfoを使う。この引数はNSDictionary型であり、キーとしてUIImagePickerControllerOriginalImageを指定する事でオリジナルデータのUIImageオブジェクトを取り出す事ができる。こちらの画像サイズは、1200 x 1600になっている。これが、iPhoneが搭載しているカメラの解像度になる。
ちなみに、UIImageが表している画像のサイズは、sizeプロパティを使って調べる事ができる。
UIImage.h
@property(nonatomic, readonly) CGSize size;
editingInfoには、同時にユーザが行った編集の情報も入っている。こちらは、UIImagePickerControllerCropRectを使って取り出す事ができる。ユーザによる編集内容を反映させたいときは、こちらも使おう。
取り出したUIImageを表示するには、UIImageViewクラスを使うのが簡単だ。これは、UIImageを表示してくれるビューである。
UIImageViewには、imageというプロパティがある。ここにUIImageオブジェクトを設定する事で、画面に表示させる事ができる。
UIImageView.h
@property(nonatomic, retain) UIImage* image;
このクラスを、ウインドウの中心に貼付けて使う事にしよう。Interface Builderで、ライブラリからドラッグ&ドロップでUIImageViewを追加する。さらに、CameraViewControllerにアウトレットを追加して、これを参照するようにしよう。
オフスクリーン描画
カメラアプリでは、撮影した写真のオリジナルデータを使いたいところだが、この画像サイズはかなり大きい。もちろん、近年のカメラに比べれば、解像度としては決して大きくない。だが、組み込みアプリケーションの中でこのサイズの画像を読み込んで使うのは、なかなか大変なものがある。メモリの容量に大きな制限があるiPhoneでは、できるだけ必要のないメモリの使用を避けたいところだ。
そこで、画像を縮小して使う事にしよう。1200 x 1600の画像を、300 x 400に縮小する事にする。画像の縮小の方法はいくつかあるが、ここではグラフィックスコンテキストを使う事にしよう。
グラフィックスコンテキストとは、描画を行う対象を表すものである。たとえば、iPhoneのスクリーンに描画を行うときは、スクリーン用に提供されるグラフィックスコンテキストを使う。それ以外にも、あるメモリ領域をビットマップ画像として確保して、そこに描画を行うグラフィックスコンテキストもある。つまり、オフスクリーン描画が行えるのだ。
オフスクリーン描画のためのグラフィックスコンテキストを作るには、UIGraphicsBeginImageContext()を使う。グラフィックスコンテキストを作成したら、そこに対して描画を行う。描画した結果は、UIImageで取得する事ができる。これには、UIGraphicsGetImageFromCurrentImageContext()を使う。最後に、オフスクリーン描画を終わりにするには、UIGraphicsEndImageContext()を呼ぼう。
UIGraphcis.h
void UIGraphicsBeginImageContext(CGSize size);
UIImage* UIGraphicsGetImageFromCurrentImageContext(void);
void UIGraphicsEndImageContext(void);
このグラフィックスコンテキストと、画像の縮小がどう関係するのか。鍵は、UIImageクラスが持つ、drawInRect:というメソッドにある。このメソッドは、現在のコンテキストに対して、指定した大きさで画像の描画を行うものだ。つまり、オフスクリーン領域に縮小した画像を描画する事で、縮小画像を得よう、という考え方だ。
この方法を使うと、画像の縮小だけでなく、別の画像やテキストの合成なども行う事ができる。
縮小と表示を行う
では、ソースコードを紹介しよう。前回のソースコードに付け加える形で実装していく。
CameraViewController.m
- (void)imagePickerController:(UIImagePickerController*)picker
didFinishPickingImage:(UIImage*)image
editingInfo:(NSDictionary*)editingInfo
{
// イメージピッカーを隠す
[self dismissModalViewControllerAnimated:YES];
// オリジナル画像を取得する
UIImage* originalImage;
originalImage = [editingInfo objectForKey:UIImagePickerControllerOriginalImage];
// グラフィックスコンテキストを作る
CGSize size = { 300, 400 };
UIGraphicsBeginImageContext(size);
// 画像を縮小して描画する
CGRect rect;
rect.origin = CGPointZero;
rect.size = size;
[originalImage drawInRect:rect];
// 描画した画像を取得する
UIImage* shrinkedImage;
shrinkedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// 画像を表示する
_imageView.image = shrinkedImage;
}
これで撮影した画像を、適切な大きさで表示できるようになった。次回は、この画像に対してエフェクトを加えてみよう。
ここまでのソースコード: Camera-3.zip