画像をぼかす、モザイク化するにはどうすればいいでしょうか。UIGraphicsBeginImageContextを使ったやり方やCALayerでラスタライズする方法もあります。
ぼかし・モザイク化
画像を拡大縮小するときに使う補間やラスタライズなどを逆手にとるとモザイクのほうなボケた画像が作り出せます。これを作り出すために
UIGraphicsBeginImageContext, UIGraphicsEndImageContext
を使う方法とCALayerを使うやり方があります。
例えば、このような画像をモザイク化してみたいと思いますので、画像をAssetsに入れます。
UIGraphicsBeginImageContext
補間:
例えば画像を100x100pixから200x200pixに拡大するときに、足りない情報が出てきます
座標の[0,0] [1,1] ….
拡大 [0,0] [1,1] [2,2] …
元の[1,1]の画像データは拡大後に[2,2]として使えますが[1,1]の画像ピクセル情報が足りない。このときに補間という作業を行います。とても単純な例では元の[0,0] と [1,1] の両方を合計して平均を出して中間データとするのです。
画像は連続性がある程度あるので、なんとなく違和感の少ない画像を作り出せます。
モザイク画像は、逆にこの補間を一切やらないということで実現できます。
以下の例は、画像を1/10縮小してそれを元に戻す、つまり拡大ですが、ここで補間させないでそのまま拡大します。
ViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 画面背景色を設定してみました self.view.backgroundColor = UIColor(red:0.99,green:0.81,blue:0.56,alpha:1.0) let img1 = UIImage(named: "mosaic")! let imgView = UIImageView(image: img1) // 画像のサイズ let iWidth = img1.size.width let iHeight = img1.size.height // 縮小:10% let scale:CGFloat = 0.1 let sWidth = iWidth * scale let sHeight = iHeight * scale // Begin ---> UIGraphicsBeginImageContext(CGSize(width: sWidth, height: sHeight)) // 元画像を10%に縮小 img1.draw(in: CGRect(x: CGFloat(0), y: CGFloat(0), width: sWidth, height: sHeight)) // 縮小した画像をimg2とする let img2 = UIGraphicsGetImageFromCurrentImageContext() // <--- End UIGraphicsEndImageContext() // Begin ---> 元画像サイズで枠を作成 UIGraphicsBeginImageContext(CGSize(width: iWidth, height: iHeight)); // 縮小した画像を元サイズに拡大(=> x10) img2?.draw(in: CGRect(x: CGFloat(0), y: CGFloat(0), width: iWidth, height: iHeight)) // 拡大した画像をimg3とする let img3 = UIGraphicsGetImageFromCurrentImageContext() // <--- End UIGraphicsEndImageContext() imgView.image = img3 let screenWidth:CGFloat = view.frame.size.width let screenHeight:CGFloat = view.frame.size.height // 画像をセンターに合わせる imgView.center = CGPoint(x: screenWidth/2, y: screenHeight/2) self.view.addSubview(imgView) } } |
このようなモザイク画像になりました。
CALayer
CALayerを使いラスタライズ化を設定します。これはベクター形式などの画像データをBMPのようなピクセル、ドットに置き換えることです。
imgView.layer.shouldRasterize = true;
ラスタライズのスケールを設定します。
imgView.layer.rasterizationScale = 0.1;
これで、それなりの画像のぼけを出せます。
ViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 画面背景色を設定してみました self.view.backgroundColor = UIColor(red:0.99,green:0.81,blue:0.56,alpha:1.0) let img1 = UIImage(named: "mosaic")! let imgView = UIImageView(image: img1) imgView.layer.shouldRasterize = true imgView.layer.rasterizationScale = 0.1 let screenWidth:CGFloat = view.frame.size.width let screenHeight:CGFloat = view.frame.size.height // 画像をセンターに合わせる imgView.center = CGPoint(x: screenWidth/2, y: screenHeight/2) self.view.addSubview(imgView) } } |
CALayerを使う方は画質は多少異なりますが、コード量は少ないです。
ちなみに、imgView.layer.rasterizationScaleを0.1にしましたが1.0でやれば綺麗な元の画像になります。
関連ページ:
- 画像UIImageViewをSwiftコードで設定する
- ストーリーボードを使った画像 UIImageView の設定
- 画像の拡大縮小 (CGRect)
- CGAffineTransform:画像を回転、移動、反転
- アニメーション(パラパラマンガ)
- Image, Text の合成
- 画像をドラッグさせる
- UIImage の使い方
- 画像をぼかす、モザイク化する
- CABasicAnimationを使たアニメーション
- cornerRadiusを使って画像を角丸にする
References:
UIGraphicsBeginImageContext(_:) – UIKit | Apple Developer Documentation
shouldRasterize – CALayer | Apple Developer Documentation