iOSでのSNSなどのプロフィール写真のトリミング

#初めに

SNSなどでのプロフィール写真のトリミングに関する方法を書いています。

# 準備
ここでは、[RSKImageCropper](https://github.com/ruslanskorb/RSKImageCropper)というライブラリーを用いて、実装を行います。
まずは、CocoaPodsでライブラリーを追加します。podfileに以下を追加して、

```
pod 'RSKImageCropper'
```

pod installします。

本ライブラリーは、objective Cで書かれているので、Swiftで使用したい場合は、掛け渡しのためのBridging_Headerファイルを作成し、以下を記述する必要があります。

```objective_c

#import <RSKImageCropper/RSKImageCropper.h>
```

#実装

あとは、LabelとButton、UIImageをViewに用意して、以下を貼り付けるだけです。

```swift
import UIKit
import RSKImageCropper
        
        class ViewController: UIViewController,RSKImageCropViewControllerDelegate,UIImagePickerControllerDelegate,
        UINavigationControllerDelegate{
            
            @IBOutlet weak var label: UILabel!
            
            @IBOutlet weak var imageView: UIImageView!
            
            
            
            override func viewDidLoad() {
                super.viewDidLoad()
                
                let savedPngdata = UserDefaults.standard.object(forKey: "userImage")
                if savedPngdata != nil {
                    
                    let savedPng = UIImage(data: savedPngdata as! Data)!
                    imageView.image = savedPng
                    
                }
                
                
            }
            
            override func didReceiveMemoryWarning() {
                super.didReceiveMemoryWarning()
            }
            
            
            
            @IBAction func button(_ sender: Any) {
                
                //アラート表示のために
                let actionSheet = UIAlertController(title: "", message: "プロフィール写真を設定します", preferredStyle: UIAlertController.Style.actionSheet)
                
                let tappedcamera = UIAlertAction(title: "カメラで撮影する", style: UIAlertAction.Style.default, handler: {
                    (action: UIAlertAction!) in
                    self.tappedcamera()
                })
                
                let tappedlibrary = UIAlertAction(title: "ライブラリから選択する", style: UIAlertAction.Style.default, handler: {
                    (action: UIAlertAction!) in
                    self.tappedlibrary()
                })
                
                let cancel = UIAlertAction(title: "キャンセル", style: UIAlertAction.Style.cancel, handler: {
                    (action: UIAlertAction!) in
                    print("キャンセル")
                })
                
                actionSheet.addAction(tappedcamera)
                actionSheet.addAction(tappedlibrary)
                actionSheet.addAction(cancel)
                
                present(actionSheet, animated: true, completion: nil)
                
                
                
                
                
            }
            
            //　撮影が完了時した時に呼ばれる
            func imagePickerController(_ imagePicker: UIImagePickerController,
                                       didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
                
                let image : UIImage = info[.originalImage] as! UIImage
                
                imagePicker.dismiss(animated: false, completion: { () -> Void in
                    
                    var imageCropVC : RSKImageCropViewController!
                    
                    imageCropVC = RSKImageCropViewController(image: image, cropMode: RSKImageCropMode.circle)
                    
                    imageCropVC.moveAndScaleLabel.text = "切り取り範囲を選択"
                    imageCropVC.cancelButton.setTitle("キャンセル", for: .normal)
                    imageCropVC.chooseButton.setTitle("完了", for: .normal)
                    imageCropVC.delegate = self
                    
                    self.present(imageCropVC, animated: true)
                    
                })
                
            }
            
            // 撮影がキャンセルされた時に呼ばれる
            func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
                picker.dismiss(animated: true, completion: nil)
            }
            
            func tappedlibrary() {
                let sourceType:UIImagePickerController.SourceType =
                    UIImagePickerController.SourceType.photoLibrary
                
                if UIImagePickerController.isSourceTypeAvailable(
                    UIImagePickerController.SourceType.photoLibrary){
                    // インスタンスの作成
                    let cameraPicker = UIImagePickerController()
                    cameraPicker.sourceType = sourceType
                    cameraPicker.delegate = self
                    self.present(cameraPicker, animated: true, completion: nil)
                    
                }
                else{
                    print("error")
                    
                }
            }
            
            func tappedcamera() {
                let sourceType:UIImagePickerController.SourceType =
                    UIImagePickerController.SourceType.camera
                // カメラが利用可能かチェック
                if UIImagePickerController.isSourceTypeAvailable(
                    UIImagePickerController.SourceType.camera){
                    // インスタンスの作成
                    let cameraPicker = UIImagePickerController()
                    cameraPicker.sourceType = sourceType
                    cameraPicker.delegate = self
                    self.present(cameraPicker, animated: true, completion: nil)
                    
                }
                else{
                    print("error")
                }
            }
            
            
            func imageCropViewController(_ controller: RSKImageCropViewController, didCropImage croppedImage: UIImage, usingCropRect cropRect: CGRect, rotationAngle: CGFloat) {
                
                
                //もし円形で画像を切り取りし、その画像自体を加工などで利用したい場合
                if controller.cropMode == .circle {
                    UIGraphicsBeginImageContext(croppedImage.size)
                    let layerView = UIImageView(image: croppedImage)
                    layerView.frame.size = croppedImage.size
                    layerView.layer.cornerRadius = layerView.frame.size.width * 0.5
                    layerView.clipsToBounds = true
                    let context = UIGraphicsGetCurrentContext()!
                    layerView.layer.render(in: context)
                    let capturedImage = UIGraphicsGetImageFromCurrentImageContext()!
                    UIGraphicsEndImageContext()
                    let pngData = capturedImage.pngData()!
                    //このImageは円形で余白は透過です。
                    let png = UIImage(data: pngData)!
                    imageView.image = png
                    
                    UserDefaults.standard.set(pngData, forKey: "userImage")
//                    self.ActivityIndicator.stopAnimating()
                    
                    dismiss(animated: true, completion: nil)
                    
                }
            }
            
            //トリミング画面でキャンセルを押した時
            func imageCropViewControllerDidCancelCrop(_ controller: RSKImageCropViewController) {
                dismiss(animated: true, completion: nil)
            }
            
            
            
            
            
}
```