MILLEN BOX

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

UIImageの一部を切り取る方法 [swift2.1]

UIImageの一部を切り取る方法について。

表示している写真に対し、セグメントコントロールでクリップする/しないを切り替えるアプリを作成しました。
f:id:anthrgrnwrld:20151115103321g:plain

githubは以下です。

▶︎GitHub - anthrgrnwrld/clipImage

参考にしたページは以下です。

▶︎UIImageの一部を切り抜く方法 | 目くじら日記

▶︎画像をトリミングしてUIImageViewにセットする - Qiita

▶︎SwiftでUIImageを回転、リサイズ、クリッピング、塗りつぶし - Qiita

自分ポイント1

下の記載がクリッピング用のメソッドです。
parameterとしては対象のUIImageと切り取りRectを指定し、Returnは切りとり後のUIImageとなります。

    /**
     UIImageを切り取る
     
     - parameter image:切り取り対象(UIImage)
     - parameter rect:切り取る大きさと座標位置(CGRect)
     - returns: 切り取り結果(UIImage)
    */
    func clipImage(image: UIImage?, rect: CGRect?) -> UIImage? {
        
        guard let originalImage = image else {
            return nil
        }
        
        guard let rct = rect else {
            return image
        }
        
        // ソース画像からCGImageを取り出し、指定された範囲を切り抜いたCGImageを生成
        let cripImageRef = CGImageCreateWithImageInRect(originalImage.CGImage, rct)
        
        guard let imgrf = cripImageRef else {
            return image
        }

        //生成したCGImageをUIImageとする
        let crippedImage = UIImage(CGImage: imgrf)
        
        return crippedImage
        
    }

自分ポイント2

自分ポイント1で再生した関数をセグコントロールをタップした時に呼び出します。

    /**
     Clip用のSegControlを押下した時
     */
    @IBAction func pressClipSegControl(sender: AnyObject) {
        
        var rect :CGRect?       //切り取るrect値格納用
        
        //セグコントロールとclipTypeを紐付け。そしてその値がnilになる場合(= Non Clip)には元のイメージを表示する
        let clipValues : [clipType?] = [nil, .type100x100]
        guard let clipValue = clipValues[clipSegControl.selectedSegmentIndex] else {
            setImage()
            return
        }

        //セグコントロールが.type100x100(= Clip(100x100))の時、それに従ったrectの値を入れる
        switch clipValue {
        case .type100x100:
            let origin = CGPoint(x: 100, y: 250)        //座標位置(四隅の左上)は(100,100)
            let size = CGSize(width: 100, height: 100)  //切り取りサイズは100x100
            rect = CGRect(origin: origin, size: size)   //originとsizeからrectを割り出す
        }
        
        //上で作成したrectに従って指定したUIImageを切り取る。今回きりとるUIImageはimageViewFromLibrary.image
        let clippedImage = clipImage(imageViewFromLibrary.image, rect: rect)    //clippedImageには切り取り結果が入る

        //clippedImageがnilの場合には元のイメージを表示する
        guard let clpImg = clippedImage else {
            setImage()
            return
        }
        
        //きりとったUIImageを表示する
        imageViewFromLibrary.image = clpImg
    }

clipTyeについてはenumで以下のように定義しておきます。

    enum clipType :Int {
        case type100x100
    }

注意点

今回の方法の場合、切り取り座標と切り取りサイズの指定はあくまでUIImageに対して指定してあげないといけません。
スクリーンの座標で考えると「思ってたんと違う」ということになってしまうので注意してください。

(関連記事を書きました!)

anthrgrnwrld.hatenablog.com