読者です 読者をやめる 読者になる 読者になる

【swift】RSKImageCropperを使って画像のトリミング

swift iPhoneアプリ開発

はじめに

今回やりたかったのは以下の画像のこんな感じのUIです


ユーザがアップロードする画像の縦横比が決まっている場合を想定しています。
ユーザのアイコン画像だったら正方形、ページ上部のヘッダー画像だったら縦横比 = 2:1とかです


で、最初自作してたんですけど他のアプリ見てると画像を拡大・縮小したり、縦長画像、横長画像など色々考慮することが多くて、、、

そこでライブラリを探していたらRSKImageCropperというライブラリがやりたいこととマッチしていてこれを使いました。助かりました

やること

導入は他のライブラリとおなじでcocoapodsからインストールして、***-Bridging-Header.hに追加します。
この辺は他と同じなので検索すればたくさん出てくるかと思います

トリミング画像を表示する
// トリミングする領域が四角の場合
// var imageCropVC: RSKImageCropViewController = RSKImageCropViewController(image: cameraImage, cropMode: RSKImageCropMode.Square)

// トリミングする領域が円形の場合
// var imageCropVC: RSKImageCropViewController = RSKImageCropViewController(image: cameraImage, cropMode: RSKImageCropMode.Custom)

// トリミングする領域をカスタマイズする場合
var imageCropVC: RSKImageCropViewController = RSKImageCropViewController(image: cameraImage, cropMode: RSKImageCropMode.Custom)

imageCropVC.delegate = self // 必須(下で実装)
imageCropVC.dataSource = self // トリミングしたい領域をカスタマイズする際には必要
self.navigationController?.pushViewController(imageCropVC, animated: true)
delegateメソッドの実装

これはトリミング画像を表示する際に必須の作業となります

class SampleViewController: RSKImageCropViewControllerDelegate {
    ・・・

    // キャンセルがおされたらトリミング画面を閉じます
    func imageCropViewControllerDidCancelCrop(controller: RSKImageCropViewController!) {
        self.navigationController?.popViewControllerAnimated(true)
    }

    // トリミング前に呼ばれるようです今回は使っていませんが、ないとコンパイルできないので定義しておきます
    func imageCropViewController(controller: RSKImageCropViewController!, willCropImage originalImage: UIImage!) {
    }

    // トリミング済みの画像がかえされます
    func imageCropViewController(controller: RSKImageCropViewController!, didCropImage croppedImage: UIImage!, usingCropRect cropRect: CGRect) {
        // 画像をサーバにアップロードするなり・・・
        // 画像を画面にセットしたり・・・
    }
}
datasourceメソッドの定義

※上のソースに追加

class SampleViewController: RSKImageCropViewControllerDelegate, RSKImageCropViewControllerDataSource {
    ・・・

    func imageCropViewControllerCustomMaskRect(controller: RSKImageCropViewController!) -> CGRect {
        
        var maskSize: CGSize
        var width, height: CGFloat!

        width = self.view.frame.width
        
        // 縦横比 = 1 : 2でトリミングしたい場合        
        height = self.view.frame.width / 2

        // 正方形でトリミングしたい場合
        height = self.view.frame.width

        maskSize = CGSizeMake(self.view.frame.width, height)
        
        var viewWidth: CGFloat = CGRectGetWidth(controller.view.frame)
        var viewHeight: CGFloat = CGRectGetHeight(controller.view.frame)
        
        var maskRect: CGRect = CGRectMake((viewWidth - maskSize.width) * 0.5, (viewHeight - maskSize.height) * 0.5, maskSize.width, maskSize.height)
        return maskRect
    }
    
    // トリミングしたい領域を描画(今回は四角な領域です・・・)
    func imageCropViewControllerCustomMaskPath(controller: RSKImageCropViewController!) -> UIBezierPath! {
        var rect: CGRect = controller.maskRect
        
        var point1: CGPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect))
        var point2: CGPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect))
        var point3: CGPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect))
        var point4: CGPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect))
        
        var square: UIBezierPath = UIBezierPath()
        square.moveToPoint(point1)
        square.addLineToPoint(point2)
        square.addLineToPoint(point3)
        square.addLineToPoint(point4)
        square.closePath()
        
        return square
    }
    
    func imageCropViewControllerCustomMovementRect(controller: RSKImageCropViewController!) -> CGRect {
        return controller.maskRect
    }

こうやって書いてみるとまぁまぁ書くことは多いんですけど、お決まりな感じですね。
あとはトリミング後の画像を小さくするなりしてサーバにアップロードするなりすればやりたいことができました。
ちなみにリサイズの方法はこちらにメモしておきました

おまけ

デフォルトだとcancelやchooseとか英語なのでこれらを日本語に書き直しました。
「RSKImageCropViewController.m」にハードコードされてました

うーん、人が作ったライブラリを使うのにもなんだかんだ1日くらいかかった、、、このアプリはいつ完成するのだろうか
と思いつつ、今日も1日が終わりました

以上です