下記のように、カメラで撮影orライブラリから選択した画像を、トリミングして表示させる機能。
トリミングをライブラリなしで実装しようとすると、時間がかかりそうだったので、下記の記事を参考に、作成しました。
https://giphy.com/gifs/xUOxfabuWp5Mgtm4OQ
[環境]
swift4.0
xcode!
https://qiita.com/KikurageChan/items/ffac3678101ecfe3de27
https://qiita.com/kazutoyo/items/dcc3cc99409852708553
流れとしては、
①cocoapodを使用して、ライブラリを導入。
②RSKImageCropperはobjectiveCのライブラリなので、Objective-C Bridging Headerを設定する。
③使用!
という流れ。
ViewController.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()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func button(_ sender: Any) {
//アラート表示のために
let actionSheet = UIAlertController(title: "", message: "プロフィール写真を設定します", preferredStyle: UIAlertControllerStyle.actionSheet)
let tappedcamera = UIAlertAction(title: "カメラで撮影する", style: UIAlertActionStyle.default, handler: {
(action: UIAlertAction!) in
self.tappedcamera()
})
let tappedlibrary = UIAlertAction(title: "ライブラリから選択する", style: UIAlertActionStyle.default, handler: {
(action: UIAlertAction!) in
self.tappedlibrary()
})
let cancel = UIAlertAction(title: "キャンセル", style: UIAlertActionStyle.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: [String : Any]) {
let image : UIImage = (info[UIImagePickerControllerOriginalImage] 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:UIImagePickerControllerSourceType =
UIImagePickerControllerSourceType.photoLibrary
if UIImagePickerController.isSourceTypeAvailable(
UIImagePickerControllerSourceType.photoLibrary){
// インスタンスの作成
let cameraPicker = UIImagePickerController()
cameraPicker.sourceType = sourceType
cameraPicker.delegate = self
self.present(cameraPicker, animated: true, completion: nil)
}
else{
print("error")
}
}
func tappedcamera() {
let sourceType:UIImagePickerControllerSourceType =
UIImagePickerControllerSourceType.camera
// カメラが利用可能かチェック
if UIImagePickerController.isSourceTypeAvailable(
UIImagePickerControllerSourceType.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 = UIImagePNGRepresentation(capturedImage)!
//このImageは円形で余白は透過です。
let png = UIImage(data: pngData)!
imageView.image = png
self.ActivityIndicator.stopAnimating()
dismiss(animated: true, completion: nil)
}
}
//トリミング画面でキャンセルを押した時
func imageCropViewControllerDidCancelCrop(_ controller: RSKImageCropViewController) {
dismiss(animated: true, completion: nil)
}
}