How to Compress/Resize Image on iOS Before Uploading to a Server

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

compress image size without losing quality before uploading to server in iPhone

While going through Stackoverdflow following this link I find out following code

 + (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return newImage;
}

Best way to optimize image before uploading to server

thanks your for your feedback.
Here is what I decided to do and is great in terms of performances : resizing to the wished resolution, then and only then do iterative compression until reachning the wished size.

Some sample code :

//Resize the image 
float factor;
float resol = img.size.height*img.size.width;
if (resol >MIN_UPLOAD_RESOLUTION){
factor = sqrt(resol/MIN_UPLOAD_RESOLUTION)*2;
img = [self scaleDown:img withSize:CGSizeMake(img.size.width/factor, img.size.height/factor)];
}

//Compress the image
CGFloat compression = 0.9f;
CGFloat maxCompression = 0.1f;

NSData *imageData = UIImageJPEGRepresentation(img, compression);

while ([imageData length] > MAX_UPLOAD_SIZE && compression > maxCompression)
{
compression -= 0.10;
imageData = UIImageJPEGRepresentation(img, compression);
NSLog(@"Compress : %d",imageData.length);
}

and

- (UIImage*)scaleDown:(UIImage*)img withSize:(CGSize)newSize{
UIGraphicsBeginImageContextWithOptions(newSize, YES, 0.0);
[img drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}

Thanks

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 compress multiple images and upload in FTP server from iPhone app?

You should definitly try out this library -> http://code.google.com/p/objective-zip/ . I've had good results zipping up to 3 images. Guess 25 will work as well

EDIT:


Here's a post of mine which has some sample code wich you can use :)

How can I convert my Zip-file to NSData to email my Zip file as an attachment



Related Topics



Leave a reply



Submit