MILLEN BOX

音楽好きの組み込みソフトエンジニアによるプログラミング(主にiOSアプリ開発)の勉強の記録

スクリーンショットをUIImageに保存する方法 [swift2.0] [UIImage] [UIView] [スクリーンショット]

こんにちは。
本日はiOS端末に表示されている画面をUIImageとして保存する方法をご紹介します。
作成したサンプルのイメージはこちら。
f:id:anthrgrnwrld:20151019195806g:plain

そしてGithubはこちらです。

▶︎ GitHub - anthrgrnwrld/screenShot2UIImage

以下のページを参考にしました。

▶︎061 UIViewからUIImageを取得する(スクリーンショット) - Swift Docs

▶︎[Objective-C] 画像処理についてのまとめ - Qiita

自分ポイント1

画面のキャプチャは以下の手順で行います。

  1. キャプチャする範囲をCGRectで指定する (今回は画面全体)
  2. 手順1で指定したサイズのコンテキストを作成する

    • コンテキストというのはモノを渡す受け皿みたいな感じか?
    • UIGraphicsBeginImageContextWithOptionsUIGraphicsGetCurrentContext を使用
  3. キャプチャしたいViewのCALayerにて renderInContext というメソッドを使って手順2で作成したコンテキストへ複写する

  4. 現在のコンテキストをUIImageに保存する

以下には、上記に則って作成したキャプチャ用関数を載せておきます。(というか参考リンク先のソースまんまですね...。)
これでスクリーンショットをUIImageに残すことができます。

class ViewController: UIViewController {
    
    ...

    /**
    スクリーンキャプチャ用関数
    
    :returns: UIImage
    */
    func GetImage() -> UIImage {
        
        // キャプチャする範囲を取得.
        let rect = self.view.bounds
        
        // ビットマップ画像のcontextを作成.
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        let context: CGContextRef = UIGraphicsGetCurrentContext()!
        
        // 対象のview内の描画をcontextに複写する.
        self.view.layer.renderInContext(context)
        
        // 現在のcontextのビットマップをUIImageとして取得.
        let capturedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
        
        // contextを閉じる.
        UIGraphicsEndImageContext()
        
        return capturedImage
    }

    @IBAction func pressScreenShotButton(sender: AnyObject) {
        
        let capturedImage = GetImage() as UIImage     // キャプチャ画像を取得.
        
        imageScreenShot.image = capturedImage
        
    }


}

自分ポイント2

自分ポイント1で一応目的は達成していますが、それだけでは成果が見えません。
ですので、本当にスクリーンショットが保存されているか確認するようなアプリを作ってみました。
ボタンを押すとスクリーンショットを撮影します。そしてその結果を"Screen Shot image is here!" に表示する簡単なアプリです。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageScreenShot: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    /**
    スクリーンキャプチャ用関数
    
    :returns: UIImage
    */
    func GetImage() -> UIImage {
        
        // キャプチャする範囲を取得.
        let rect = self.view.bounds
        
        // ビットマップ画像のcontextを作成.
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        let context: CGContextRef = UIGraphicsGetCurrentContext()!
        
        // 対象のview内の描画をcontextに複写する.
        self.view.layer.renderInContext(context)
        
        // 現在のcontextのビットマップをUIImageとして取得.
        let capturedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
        
        // contextを閉じる.
        UIGraphicsEndImageContext()
        
        return capturedImage
    }

    @IBAction func pressScreenShotButton(sender: AnyObject) {
        
        let capturedImage = GetImage() as UIImage     // キャプチャ画像を取得.
        
        imageScreenShot.image = capturedImage
        
    }


}

今回は撮影した結果をそのまんま表示してみるアプリを作成しましたが、取得したUIImageをどのように使用するかはあなた次第。
ツイートする際に添付してもいいし、自動で画像処理・加工してカメラロールに保存してもよいし。
これだけで色々アイデア広がりますね。