2018年7月8日日曜日

特定の色を透明にする

やりたいこと

画像の特定の色(例えばグレーの部分とか)だけを透明にしたい。
(別な画像と合成する時に使うのだ)

やり方

let maskColor:[CGFloat] = [188, 188, 188, 188, 188, 188]
let maskedImage = cgImage?.copy(maskingColorComponents: maskColor)


Core Graphicsの機能を使うので、画像をCGImageに変換しておく。(例では変数cgImageとして用意)

maskColorの配列が、透明化したい色を範囲として指定するための引数。はっきりはわかってないんだけど、要素0から順に、Rの下限、上限、Gの下限、上限、Bの下限、上限を0〜255の値で指定するようだ。
一色だけなら全部同じ値にすればいいし(CIFilterのポスタリゼーションで作った3階調のグレー色は188だった)、色の範囲で指定するならそれぞれの下限値、上限値を変えればいい。

実際に透過処理をしてるのがCGImageのcopyメソッド。処理が終わったCGImageを返す。
合成処理をするならCGImageのままかCIImageがいい。というか、macOSでNSImageに変換したら透明じゃなくなってしまった。

リファレンス見ると最後にCGImageをreleaseしろって書いてあるんで、そうした方がいいみたい。

注意

元画像にαチャンネルがあるとnilが返ってきてしまうので、あらかじめα情報を取り除く作業をしておかないといけない。そうしないと予期せぬエラーでアプリが落ちてしまう。

UIGraphicsの作り直しのOptionで第2引数のopaqueをtrueにすればOK。

UIGraphicsBeginImageContextWithOptions(srcImage.size, true, 0.0)
srcImage.draw(in: CGRect(origin: CGPoint.zero, size: srcImage.size))
let remakedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

0 件のコメント:

コメントを投稿