How to Get the Edited Image from Uiimagepickercontroller in Swift

How can I really edit image by using UIImagePickerController.InfoKey.editedImage in swift?

Step-1: Tap and hold the Option key (⌥) on the keyboard and click on the selected image on the Simulator. You'll see two Solid, Gray buttons showing up where your mouse cursor is, just the same as a user would use their Index finger and Thumb to Pinch and Zoom an image (screenshot attached).

Sample Image

Step-2: Drag the image on the Simulator. You'll be able to crop the selected image by zooming in (screenshot attached). Can move the image also, by unholding the Option key (⌥) from your keyboard.

Sample Image

Step-3: Finally, the info[.editedImage] will get the user's edited/modified image in the imagePickerController: didFinishPickingMediaWithInfo: method.

Always return edited image from UIImagePickerController

I use a library called TOCropViewController

So, in my didFinishPickingMedia I have:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage{
dismiss(animated: true, completion: nil)
let cropVC = TOCropViewController(image: pickedImage)
cropVC.delegate = self
cropVC.aspectRatioPickerButtonHidden = true
cropVC.aspectRatioPreset = .presetSquare //Here you can set the ratio as 4.3, 4.2, square, etc
cropVC.aspectRatioLockEnabled = true //Here you lock the ratio
cropVC.resetAspectRatioEnabled = false
self.present(cropVC, animated: true, completion: nil)
}
}

func cropViewController(_ cropViewController: TOCropViewController, didCropTo image: UIImage, with cropRect: CGRect, angle: Int) {
self.yourImage.image = image
cropViewController.dismiss(animated: true, completion: nil)
}

So, when the user takes a picture or select one from the photo library, the Image Picker closes and the Crop View Controller opens. There, the user can crop with a specific ratio. With the cropViewController didCropTo function you get the cropped image to use it as you want.

How to pass selected image from UIImagePicker to the UIViewController

In your form, have you implemented a UIImageView? If it's the case, in your

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])

you can say:

myFormImageView.image = selectedImageFromPicker

and then when you submit your form you can upload the form info + the image data

UPDATE:

My approach by subclassing UIIMagePickerController

import UIKit

protocol ImagePickerDelegate {
func imagePicked(image: UIImage)
}

class myPickerViewController: UIImagePickerController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{

var imagePickerDelegate:ImagePickerDelegate!

override func viewDidLoad() {
super.viewDidLoad()
allowsEditing = true
delegate = self
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
imagePickerDelegate.imagePicked(image: selectedImage)
dismiss(animated: true, completion: nil)
}

}

class ViewController : UIViewController, ImagePickerDelegate {

func imagePicked(image: UIImage) {
imagePicked = image
}

var imagePicked:UIImage! {
didSet {
imageView.image = imagePicked
}
}

let button: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Select an image", for: .normal)
button.backgroundColor = .red
button.addTarget(self, action: #selector(handleImagePicker), for: .touchUpInside)
return button
}()

let imageView: UIImageView = {
let iv = UIImageView()
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFill
iv.layer.masksToBounds = true
iv.layer.borderWidth = 2
iv.layer.borderColor = UIColor.black.cgColor
return iv
}()

override func viewDidLoad() {
super.viewDidLoad()

title = "Get image via Delegate"
view.backgroundColor = .white

view.addSubview(button)
view.addSubview(imageView)

button.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100).isActive = true
button.heightAnchor.constraint(equalToConstant: 30).isActive = true
button.widthAnchor.constraint(equalToConstant: 150).isActive = true
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true

imageView.topAnchor.constraint(equalTo: self.button.topAnchor, constant: 50).isActive = true
imageView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 20).isActive = true
imageView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -20).isActive = true
imageView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -50).isActive = true

}

@objc func handleImagePicker() {
let myPickerVC = myPickerViewController()
myPickerVC.imagePickerDelegate = self

self.present(myPickerVC, animated: true, completion: nil )
}

}

You create a new project and paste the entire code it will works, I guess, like me.
Hope it helps

Always return edited image from UIImagePickerController

I use a library called TOCropViewController

So, in my didFinishPickingMedia I have:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage{
dismiss(animated: true, completion: nil)
let cropVC = TOCropViewController(image: pickedImage)
cropVC.delegate = self
cropVC.aspectRatioPickerButtonHidden = true
cropVC.aspectRatioPreset = .presetSquare //Here you can set the ratio as 4.3, 4.2, square, etc
cropVC.aspectRatioLockEnabled = true //Here you lock the ratio
cropVC.resetAspectRatioEnabled = false
self.present(cropVC, animated: true, completion: nil)
}
}

func cropViewController(_ cropViewController: TOCropViewController, didCropTo image: UIImage, with cropRect: CGRect, angle: Int) {
self.yourImage.image = image
cropViewController.dismiss(animated: true, completion: nil)
}

So, when the user takes a picture or select one from the photo library, the Image Picker closes and the Crop View Controller opens. There, the user can crop with a specific ratio. With the cropViewController didCropTo function you get the cropped image to use it as you want.

How to get image from UIImagePickerController and Pass to next VC

  1. You need to assign the delegate to your image picker so that the appropriate methods to be called. In your loadImageButtonTapped function, don't forget to assign the image picker delegate.

Then, you should implement this method:

    func imagePickerController (_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){ 
// check if an image was selected,
// since a images are not the only media type that can be selected
if let img = info[.originalImage] {
methodToPassImageToViewController(img)
}

If you need to find out the size of the image, you cann access it's size property.


  1. To pass the image to another view controller, you could use one of these two options:

    • you could use delegation
    • you could use this function for when you navigate from your view controller to another one using storyboard segues:

      func prepareForSegue(_ segue: UIStoryboardSegue, sender sender: AnyObject?) 
      {
      var destinationController = segue.destinationViewController
      // now you can pass the image to the destination view controller
      }

P.S: didFinishPickingImage is deprecated since iOS 3, you should not use that method.

iOS, Swift, UIImagePicker allows editing crop tool removes transparency. Is there fix?

By default UIImagePickerController removes the alpha channels in the edited image. To get that transparency you have to edit image yourself. Implement delegate method like this:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

if let cropRect = info[UIImagePickerControllerCropRect] as? CGRect {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
let imageRef: CGImage = image.cgImage!.cropping(to: cropRect)!

let image1: UIImage = UIImage(cgImage: imageRef, scale: image.scale, orientation: image.imageOrientation)

imageView.image = image1
picker.dismiss(animated: true, completion: nil)

}

}

}


Related Topics



Leave a reply



Submit