[iOS][Swift3.0] 画像をマスクする

2017.02.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

iOSでは画像をマスクとして任意の形に切り抜くことが出来ます。

マスクの画像は、白をブロックし黒を透過させます。

Sample1

なので切り抜きたい部分を白→灰色にすると半透明な感じになります。

Sample2

透明な背景に黒で書かれているイラストはマスク画像として機能しません。(イラストが白色であればマスクされます)

Sampe3

環境

今回は下記環境で試しています。

Xcode 8.2.1
Swift 3.0.2

実装

下記がマスクを適用する元画像とマスク用の画像とします。

// 元画像
let image = UIImage(named:"image")
// マスク用画像
let maskImage = UIImage(named:"mask")

マスク画像をCGImageにしてマスクを作成します。

let maskRef = maskImage!.cgImage,
let mask = CGImage(maskWidth: maskRef.width,
                               height: maskRef.height,
                               bitsPerComponent: maskRef.bitsPerComponent,
                               bitsPerPixel: maskRef.bitsPerPixel,
                               bytesPerRow: maskRef.bytesPerRow,
                               provider: maskRef.dataProvider!,
                               decode: nil,
                               shouldInterpolate: false)

元画像をCGImageにして.masking()でマスクを適用します。さいごにCGImageをUIImageに直しておけばOKです。

let ref = image!.cgImage
let output = ref.masking(mask)
let outputImage = UIImage(cgImage: output!)

サンプルコード

UIImageのExtensionにすると使いやすいかもしれません。

UIImage+Extension.swift

import UIKit
extension UIImage {
    func mask(image: UIImage?) -> UIImage {
        if let maskRef = image?.cgImage,
           let ref = cgImage,
           let mask = CGImage(maskWidth: maskRef.width,
                               height: maskRef.height,
                               bitsPerComponent: maskRef.bitsPerComponent,
                               bitsPerPixel: maskRef.bitsPerPixel,
                               bytesPerRow: maskRef.bytesPerRow,
                               provider: maskRef.dataProvider!,
                               decode: nil,
                               shouldInterpolate: false),
            let output = ref.masking(mask) {
            return UIImage(cgImage: output)
        }
        return self
    }
}

呼び出し側

imageView.image = UIImage(named: "image")?.mask(image: UIImage(named:"mask"))

さいごに

Swift3.0から呼び出し方が、

  • CGImageMaskCreate() → CGImage(maskWidth: ...
  • CGImageCreateWithMask() → .masking()

と、変わっていますが、基本的な処理内容は今までと同じです。

尚、マスク画像についての詳細は下記のサイトが分かりやすかったです。
http://chicketen.blog.jp/archives/16515915.html