Posted at

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


初めに

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


準備

ここでは、RSKImageCropperというライブラリーを用いて、実装を行います。

まずは、CocoaPodsでライブラリーを追加します。podfileに以下を追加して、

pod 'RSKImageCropper'

pod installします。

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


#import <RSKImageCropper/RSKImageCropper.h>


実装

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

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)
}

}