Search code examples
iosswiftparse-platformuiimage

How to compress of reduce the size of an image before uploading to Parse as PFFile? (Swift)


I was trying to upload an image file to Parse after taking photo directly on phone. But it throws an exception:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'PFFile cannot be larger than 10485760 bytes'

Here is my code:

In first view controller:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "getImage")
    {
        var svc = segue.destinationViewController as! ClothesDetail
        svc.imagePassed = imageView.image
    }
}

In view controller that uploads image:

let imageData = UIImagePNGRepresentation(imagePassed)
let imageFile = PFFile(name: "\(picName).png", data: imageData)

var userpic = PFObject(className:"UserPic")
userpic["picImage"] = imageFile`

But I still need to upload that photo to Parse. Is there any way to reduce the size or resolution of the image?


Solution

  • Yes you can use UIImageJPEGRepresentation instead of UIImagePNGRepresentation to reduce your image file size. You can just create an extension UIImage as follow:

    Xcode 8.2 • Swift 3.0.2

    extension UIImage {
        enum JPEGQuality: CGFloat {
            case lowest  = 0
            case low     = 0.25
            case medium  = 0.5
            case high    = 0.75
            case highest = 1
        }
    
        /// Returns the data for the specified image in JPEG format.
        /// If the image object’s underlying image data has been purged, calling this function forces that data to be reloaded into memory.
        /// - returns: A data object containing the JPEG data, or nil if there was a problem generating the data. This function may return nil if the image has no data or if the underlying CGImageRef contains data in an unsupported bitmap format.
        func jpeg(_ quality: JPEGQuality) -> Data? {
            return UIImageJPEGRepresentation(self, quality.rawValue)
        }
    }
    

    edit/update:

    Xcode 10 Swift 4.2

    extension UIImage {
        enum JPEGQuality: CGFloat {
            case lowest  = 0
            case low     = 0.25
            case medium  = 0.5
            case high    = 0.75
            case highest = 1
        }
    
        /// Returns the data for the specified image in JPEG format.
        /// If the image object’s underlying image data has been purged, calling this function forces that data to be reloaded into memory.
        /// - returns: A data object containing the JPEG data, or nil if there was a problem generating the data. This function may return nil if the image has no data or if the underlying CGImageRef contains data in an unsupported bitmap format.
        func jpeg(_ jpegQuality: JPEGQuality) -> Data? {
            return jpegData(compressionQuality: jpegQuality.rawValue)
        }
    }
    

    Usage:

    if let imageData = image.jpeg(.lowest) {
        print(imageData.count)
    }