初めに
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)
}
}