Steve
Steve

Reputation: 1153

Swift PNG Image being saved with incorrect orientation

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!)
                }
        })
    }

Upvotes: 12

Views: 4879

Answers (3)

Kirill
Kirill

Reputation: 879

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

let imageData = image.jpegData(compressionQuality: 1.0)

Upvotes: 2

Juan David Torres
Juan David Torres

Reputation: 1939

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
}

Upvotes: 2

Leo Dabus
Leo Dabus

Reputation: 236370

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.sstatic.net/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)
}

Upvotes: 25

Related Questions