2017年3月8日水曜日

画像の合成、初歩の初歩

ある画像の上に別の画像を合成したい場合の初歩的な覚書。

UIGraphicsのImageContextを使う。これは要するにオフスクリーン描画領域。画面に表示する前の画像を扱うために確保するメモリ領域だな。
メモリ領域と言ってもwidthとheightのsizeで大きさを指定して作る。

使い方は難しくないけどちょっと変わっていて、Contextを作る
UIGraphicsBeginImageContext(CGSize)
UIGraphicsEndImageContext()
で挟まれた間に処理を書くことになる。

作られたContextは明確な変数に入るわけじゃないようだが、イメージに対してのdrawメソッドや、レイヤーに対してのrenderメソッドなどを書くとContextに対して描画が行われる。
例)
let img = UIImage(named: "ufoImage")
img?.draw(in: CGRect(origin: CGPoint.zero, size: view.frame.size))

上記はimgの画像Contextに描画するというものであり、img描画するわけじゃないからね。

いくつかUIImageを用意して順番にContextにdrawしてやれば、重ねられた合成画像が得られるわけだ。
いろいろ処理した後の画像は
UIGraphicsGetImageFromCurrentImageContext()
関数で得ることができる。(これは引数なし)

実際のコード

//画像の準備
let backImg = UIImage(named: "backImage"//背景画像
let ufoImg = UIImage(named: "ufoImage"//上に合成する画像
//オフスクリーンのContext作る
UIGraphicsBeginImageContext(view.frame.size)
//背景をContextに描画
backImage?.draw(in: CGRect(origin: CGPoint.zero, size: view.frame.size))
//合成する画像を位置を指定して描画
ufoImg?.draw(in: CGRect(x: view.frame.midX, y: view.frame.midY, width: 50, height: 50))
//context上に合成された画像を得る
let compositedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

Contextは多用途

このContextを使うのは当然画像合成だけじゃなくいろいろ使える。
UIImageとCGImageなんかを取っ替え引っ替えいじってると画像の傾きがおかしくなったりすることもあるんだけど、そういう時にUIImageやCGImageなどの仕様上の呪縛(制約)から解放した画像を作り、あらためてUIImageを作り直してやるとかにも使える。

でかいサイズの画像を小さいサイズのContextに描画してやるとサイズ縮小ができたりとか。

まだよくわかってないことも多いので、いずれあらためて書くかも。

0 件のコメント:

コメントを投稿