matthew matthew - 7 months ago 175
Swift Question

Swift 2.0 Xcode 7.1 image picker front camera image rotated when picked

I have a tableview that displays people with an imageview and label. When a person is inserted into the table it can pull from contacts and the images look fine. When a person is not added using contacts it pulls the name from a text field and an image picker is presented for the camera. If I take a picture from the rear camera no issues. If I take a picture from the front facing camera, then the picture is off based on screen orientation. Even if the screen isn't rotated when taking the picture it is off based on the following:

If orientation is portrait, image is rotated 180 degrees.
If orientation is landscape left, image is rotated 90 degrees left.
if orientation is upside down, image is rotated 90 degrees right.
if orientation is landscape right, image is fine.

Here is my code to present the image picker:

func pickImage(){
// create the alert controller, give it three actions: library, camera, cancel
let pickerAlert = UIAlertController(title: "Add Pic?", message: "Would you like to add a picture for this person?", preferredStyle: .Alert)
// create the library action
let libAction = UIAlertAction(title: "Select photo from library", style: .Default) { (alert) -> Void in
// set picker type to the library and present the picker
self.picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(self.picker, animated: true, completion: nil)
}
// if the camera is available on the device create the camera action and add it to the picker alert
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){
let camAction = UIAlertAction(title: "Take a picture", style: .Default) { (alert) -> Void in
// set picker type to the camera and present the picker
self.picker.sourceType = UIImagePickerControllerSourceType.Camera
self.picker.modalPresentationStyle = .FullScreen
self.presentViewController(self.picker, animated: true, completion: nil)
}
pickerAlert.addAction(camAction)
}
// create the cancel action, set the person's image to contacts
let cancel = UIAlertAction(title: "Don't Add Image", style: .Cancel, handler: nil)

pickerAlert.addAction(libAction)
pickerAlert.addAction(cancel)

self.presentViewController(pickerAlert, animated: true, completion: nil)
}


Here is my imagePicker delegate: (not including didCancel, it just dismisses the picker)

func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
let imgData = UIImagePNGRepresentation(image)
saveToList(personName, imgData: imgData!)
self.tableView.reloadData()
self.dismissViewControllerAnimated(true, completion: nil)}


Surely it can't be me converting the image to PNG data? Those methods are pretty basic too. I don't have a lot going on with the picker. The save to list method simply takes the name and image data and stores it in my data model. When I retrieve the image in the cell I set the imageview image using the person's image data. I have read through the Apple documentation for the image picker and can't seem to find what I am missing :-(

Answer

Swap out the UIImagePNGRepresentation and use UIImageJPEGRepresentation instead. PNGs aren't saved with orientation information automatically. Unless you are doing a photo specific app where photo quality has to be perfect, JPGs are fine.

The UIImageJPEGRepresentation will ask for the image data but also a CGFloat to set the compression quality. It's from 0.0 to 1.0 (best).

Good Luck!