12

If I use the image before it is saved it is normal. But if I save it and use it later is is 90 degrees turned. How can I make sure it doesn't save sideways?

func saveEvent(_ center1: CLLocation, title2: String, imagePicked1: UIImage)
    {
        let data = UIImagePNGRepresentation(imagePicked1);///
        let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(NSUUID().uuidString+".dat")
        do {
            try data!.write(to: url!, options: [])
        } catch let e as NSError {
            print("Error! \(e)");
            return
        }
        let image11 = CKAsset(fileURL: url!)

        self.eventRecord.setObject(image11 as CKAsset, forKey: "Picture")
        let publicData = CKContainer.default().publicCloudDatabase
            publicData.save(self.eventRecord, completionHandler: { record, error in
                if error == nil
                {
                    print("Image saved")
                }else{
                    print(error!)
                }
        })
    }
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
Steve
  • 1,121
  • 1
  • 12
  • 32

3 Answers3

25

If you need to save your PNG with correct rotation you will need to redraw your image if its orientation it is not .up. You can redraw it as follow:

extension UIImage {
    func png(isOpaque: Bool = true) -> Data? { flattened(isOpaque: isOpaque)?.pngData() }
    func flattened(isOpaque: Bool = true) -> UIImage? {
        if imageOrientation == .up { return self }
        UIGraphicsBeginImageContextWithOptions(size, isOpaque, scale)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(origin: .zero, size: size))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

edit/update:

For iOS10+ tvOS10+ you can use UIGraphicsImageRenderer:

extension UIImage {
    func png(isOpaque: Bool = true) -> Data? { flattened(isOpaque: isOpaque).pngData() }
    func flattened(isOpaque: Bool = true) -> UIImage {
        if imageOrientation == .up { return self }
        let format = imageRendererFormat
        format.opaque = isOpaque
        return UIGraphicsImageRenderer(size: size, format: format).image { _ in draw(at: .zero) }
    }
}

Playground testing:

Usage for images without transparency:

let image = UIImage(data: try! Data(contentsOf: URL(string: "https://i.stack.imgur.com/varL9.jpg")!))!

if let data = image.png() {
    let imageFromPNGData = UIImage(data: data)
}

With transparency :

if let data = image.png(isOpaque: false) {
    let imageFromPNGData = UIImage(data: data)
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • 2
    This is the only answer that worked for me, I searched for days. Thank you very much. – Alisson Enz Mar 14 '18 at 22:06
  • This is amazing, but I'm having a job converting this flattened data back to a UIImage with UIImage(data: . This method seems to reject the png data. Do you know of a solution? – Geoff H Nov 15 '18 at 19:55
  • @GeoffH This is a new image context. You can save it as JPEG or PNG. Feel free to open a new question with a minimum verifiable example I will take a look at it if you wish – Leo Dabus Nov 15 '18 at 23:44
2

You can use this as well to prevent it from changing of orientation.

func rotateImage(image: UIImage) -> UIImage? {
    if (image.imageOrientation == UIImage.Orientation.up ) {
        return image
    }
    UIGraphicsBeginImageContext(image.size)
    image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
    let copy = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return copy
}
aheze
  • 24,434
  • 8
  • 68
  • 125
Juan David Torres
  • 1,929
  • 1
  • 6
  • 7
2

Just convert the image to JPEG data instead. No need to redraw your image:

let imageData = image.jpegData(compressionQuality: 1.0)

Kirill
  • 738
  • 10
  • 26