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).
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.
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
- 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.
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
Class Level or Struct Level Method in Swift Like Static Method in Java
Swiftui Views with a Custom Init
How to Apply Shadow to Interior Views in Swiftui
Code Migration from Swift 2.X to Swift 4
Dispatch_Once_T' Is Unavailable in Swift: Use Lazily Initialized Globals Instead
Unknown Selected Data Source for Port Speaker (Type: Speaker)
Reducing the Number of Brackets in Swift
What's the Difference Between a Required Initializer and a Designated Initializer
Prettier Debug Output Printing Swift Dictionary in Xcode
Error Using Associated Types and Generics
Subclass of Skspritenode in .Sks File
Variable Captured by Closure Before Being Initialized
Scenekit - Get Direction of Camera
Value for Swift_Version Cannot Be Empty
Using Apple's New Audioengine to Change Pitch of Audioplayer Sound
Guarantees About the Lifetime of a Reference in a Local Variable