はじめに
UIViewをモノクロにしたUIImageを出力する実装をしてみました。
以下のOSSを大変参考にさせていただきました。
https://github.com/freshking/BKFilterView
実装
考え方は簡単で、UIViewをUIImageにし、CIFilterで彩度をいじるだけです。
以下のような画面でサンプル実装しました。
BaseView:画面上部の赤いUIView
ImageView:画面下部のモノクロImageを表示するUIImageView

ボタン押下時に実装したフィルター処理
// 画面におけるBaseViewの部分を切り取り描画する
var screenshot: UIImage?
UIGraphicsBeginImageContextWithOptions(self.baseView.frame.size, false, UIScreen.main.scale)
if let imageContext = UIGraphicsGetCurrentContext() {
imageContext.translateBy(x: -self.view.frame.origin.x, y: -self.view.frame.origin.y)
self.baseView.layer.render(in: imageContext)
screenshot = UIGraphicsGetImageFromCurrentImageContext()
}
screenshot = UIGraphicsGetImageFromCurrentImageContext()
screenshot?.draw(in: self.baseView.frame)
// 描画したContextを取得し、Filterをかける。
guard let context = UIGraphicsGetCurrentContext(),
let originalImage = context.makeImage(),
let bwFilter = CIFilter(name: "CIColorControls") else {
return UIGraphicsEndImageContext()
}
let ciImage = CIImage(cgImage: originalImage)
bwFilter.setValue(ciImage, forKey: kCIInputImageKey)
// 彩度を下げる
bwFilter.setValue(NSNumber(value: 0.0), forKey: kCIInputSaturationKey)
// Contextにフィルターをかけ、UIImageを描画する。
if let bwFilterOutput = bwFilter.outputImage {
let outputImage: UIImage = UIImage(ciImage: bwFilterOutput)
outputImage.draw(in: self.baseView.frame)
self.imageView.image = outputImage
}
UIGraphicsEndImageContext()
おわりに
あまり使うことはないかもしれませんが、いつか誰かの参考になれば!
以下にソースコード全体をアップロードしております。
https://github.com/y-negi/UIViewFilteredImage