How to Compress of Reduce the Size of an Image Before Uploading to Parse as Pffile? (Swift)

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

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

swift ios reduce image size before upload

you can resize your image first to smaller size using these extension by resizing it by percent or width

extension UIImage {
func resizeWithPercent(percentage: CGFloat) -> UIImage? {
let imageView = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: size.width * percentage, height: size.height * percentage)))
imageView.contentMode = .ScaleAspectFit
imageView.image = self
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
imageView.layer.renderInContext(context)
guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
UIGraphicsEndImageContext()
return result
}
func resizeWithWidth(width: CGFloat) -> UIImage? {
let imageView = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))))
imageView.contentMode = .ScaleAspectFit
imageView.image = self
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
imageView.layer.renderInContext(context)
guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
UIGraphicsEndImageContext()
return result
}
}

to use it just call it like this

myImage = myImage.resizeWithWidth(700)!

Now next you can still compress it using compression ratio of your choice

let compressData = UIImageJPEGRepresentation(myImage, 0.5) //max value is 1.0 and minimum is 0.0
let compressedImage = UIImage(data: compressData!)

How do I resize the UIImage to reduce upload image size

Swift 5.4 & Xcode 13

I was not satisfied with the solutions here, which generate an image based on a given KB size, since most of them used .jpegData(compressionQuality: x). This method won't work with large images, since even with compression quality set to 0.0, the large image will remain large, e.g. a 10 MB produced by portrait mode of a newer iPhone still will be above 1 MB with compressionQuality set to 0.0.

Therefore I used some answers here and rewrote a Helper Struct which converts an image in a background que:

import UIKit

struct ImageCompressor {
static func compress(image: UIImage, maxByte: Int,
completion: @escaping (UIImage?) -> ()) {
DispatchQueue.global(qos: .userInitiated).async {
guard let currentImageSize = image.jpegData(compressionQuality: 1.0)?.count else {
return completion(nil)
}

var iterationImage: UIImage? = image
var iterationImageSize = currentImageSize
var iterationCompression: CGFloat = 1.0

while iterationImageSize > maxByte && iterationCompression > 0.01 {
let percantageDecrease = getPercantageToDecreaseTo(forDataCount: iterationImageSize)

let canvasSize = CGSize(width: image.size.width * iterationCompression,
height: image.size.height * iterationCompression)
UIGraphicsBeginImageContextWithOptions(canvasSize, false, image.scale)
defer { UIGraphicsEndImageContext() }
image.draw(in: CGRect(origin: .zero, size: canvasSize))
iterationImage = UIGraphicsGetImageFromCurrentImageContext()

guard let newImageSize = iterationImage?.jpegData(compressionQuality: 1.0)?.count else {
return completion(nil)
}
iterationImageSize = newImageSize
iterationCompression -= percantageDecrease
}
completion(iterationImage)
}
}

private static func getPercantageToDecreaseTo(forDataCount dataCount: Int) -> CGFloat {
switch dataCount {
case 0..<3000000: return 0.05
case 3000000..<10000000: return 0.1
default: return 0.2
}
}
}

Compress an image to max 1 MB:

        ImageCompressor.compress(image: image, maxByte: 1000000) { image in
guard let compressedImage = image else { return }
// Use compressedImage
}
}

how to reduce size of the image in swift ios

The compression quality passed in to UIImageJPEGRepresentation determines the image quality your JPEG image will be. You have 0.5, try something lower like 0.1:

let imageData = UIImageJPEGRepresentation(newImage!, 0.1)! as Data

From Apple's Docs:

compressionQuality
The quality of the resulting JPEG image, expressed as a value from 0.0 to 1.0. The value 0.0 represents the maximum compression (or lowest quality) while the value 1.0 represents the least compression (or best quality).

Reduce the file size of png image

I'm compressing to WebP formate which providing around 3X smaller file sizes compared to PNG as I'm to create WhatsApp sticker pack, which also accepts WebP

Reduce Parse PFFile, images and text

You should to resize the picture to make sure it is small size for upload. See this answer



Related Topics



Leave a reply



Submit