背景
広告付きアプリを開発している際にスクリーンショットを利用したくなったが、広告が邪魔で加工せねばならなかった。綺麗にスクリーンショットを撮る方法のひとつをまとめておく。
とりあえずソース
import UIKit
extension UIView {
//広告を隠したスクリーンショットを撮る関数(WindowFrameが画面領域、adFrameが広告領域)
func getScreenShot(windowFrame: CGRect, : adFrame: CGRect) -> UIImage {
//context処理開始
UIGraphicsBeginImageContextWithOptions(windowFrame.size, false, 0.0);
//UIGraphicsBeginImageContext(windowFrame.size); <-だめなやつ
//context用意
let context: CGContext = UIGraphicsGetCurrentContext()!;
//contextにスクリーンショットを書き込む
layer.render(in: context);
//広告の領域を白で塗りつぶす
context.setFillColor(UIColor.white.cgColor);
context.fill(adFrame);
//contextをUIImageに書き出す
let capturedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()!;
//context処理終了
UIGraphicsEndImageContext();
//UIImageをreturn
return capturedImage;
}
}
解説
UIViewControllerにいちいちスクリーンショットのコードを書いたりメソッドを置くのも面倒なので、UIViewクラスを拡張してしまった。上のソースコードを適当な名前.swiftでプロジェクトファイルに突っ込んでおけば、UIViewを継承するどの場面でもスクリーンショットが撮れるので便利。
スクリーンショットを撮るには、UIGraphicsとCGContextを用いれば良い。スクリーンショット用のUIImageと広告を隠す用のUIImageをそれぞれ用意して合成しても良いが、一つのcontextに同時に書き込んでしまうとコード量も短くて楽。
罠(注意)
UIGraphicsBeginImageContext() と UIGraphicsBeginImageContextWithOptions() の二種類がXcodeの候補に出てくる。一見前者で行けるように思えるが(Swift3らしさ的に)、これだとなぜかスクリーンショットの画質が劣化してしまう。iPhone等で見たまんまの綺麗なスクリーンショットを取りたいならば、後者のオプション付きメソッドを利用する事。