0

I am stumped and hoping someone can give me some break crumbs to research. I searched but couldn't find the same question, so I apologize if it has been asked and answered before.

I have a simple app where a user can upload photos to a post on Parse-Server using:

@IBAction func SelectImage(_ sender: Any) {
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
    imagePicker.allowsEditing = false
    self.present(imagePicker, animated: true, completion: nil)
}

If it is the first image I set a UIImageView to the selected image and add it to an array of PFFiles. If its not the first I just add it to the array. I then set a collection view to show all the images in the PFFile array.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        if !image1Set {
            blipImage.image = image
            imagePicked = true
            image1Set = true
        } else if !image2Set {
            image2Set = true
        } else if !image3Set {
            image3Set = true
        }
        // Build an array of the files for the blip
        if let imageData = UIImagePNGRepresentation(image) {
            if let blipFile = PFFile(name: "image.png", data: imageData) {
                newBlipFiles.append(blipFile)
                blipFiles.append(blipFile)
            }
        }
        blipFileCollectionView.reloadData()
    }
    dismiss(animated: true, completion: nil)
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell:BlipMainCell = collectionView.dequeueReusableCell(withReuseIdentifier: "fileCell", for: indexPath) as! BlipMainCell

    blipFiles[indexPath.row].getDataInBackground { (data, error) in
        if let imageData = data {
            if let imageToDisplay = UIImage(data: imageData) {
                cell.image.image = imageToDisplay
            }
        }
    }
    return cell
}

When I run this on the simulator everything looks fine. When I test this on the phone though the photo in the collection view flips it on its side. Once the photo is read into the server and the previously uploaded image is seeded into the same view controller the image is flipped on the collection view AND in the UIImageView that originally showed it correctly. When the image is pulled from the server and used as the icon in a table view it is also flipped.

My hypothesis is that something happens when the image is converted into data using UIImagePNGRepresentation(image) such that the orientation is stripped away. This would explain why all the times its read as a PFFile it is flipped but not the original setting, yet when it seeds that same UIImageView that was fine it gets flipped.

Can anyone help me understand this? In my heart of hearts I am hoping this is as simple as adding somekind of argument to the data encoding of the PFFile such that the UIImagePNGRepresentation(image) retains the correct orientation. Very frustrating though because there is no way I can have an app where the orientation doesn't math what the user expects because that is what they see in their camera roll.

Thanks, dan

Daniel Patriarca
  • 361
  • 3
  • 20

2 Answers2

1

This is because when you convert your UIImage object to PNG data representation it discards the image exif metadata including the image orientation information. The solution is to use JPEG data representation which preserves the image orientation and also has the advantage of reducing the image data size. If you really need to upload a PNG you can redraw your image in a new image context and then convert the new image to data.

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
1

The problem is you had the correct data but you threw it away when you fetched the UIImagePickerControllerOriginalImage. That is the wrong key if you intend to upload the image data. You wanted the UIImagePickerControllerImageURL. That is the data, on disk. Upload it without messing with it first!

matt
  • 515,959
  • 87
  • 875
  • 1,141