How to compress/resize image on iOS before uploading to a server?
Solution 1
You should be able to make a smaller image by doing something like
UIImage *small = [UIImage imageWithCGImage:original.CGImage scale:0.25 orientation:original.imageOrientation];
(for a quarter-size image) then convert the smaller image to a PNG or whatever format you need.
Solution 2
This snippet will resize the image:
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The variable newSize
is a CGSize
and can be defined like so:
CGSize newSize = CGSizeMake(100.0f, 100.0f);
Solution 3
A self-contained solution:
- (UIImage *)compressForUpload:(UIImage *)original scale:(CGFloat)scale
{
// Calculate new size given scale factor.
CGSize originalSize = original.size;
CGSize newSize = CGSizeMake(originalSize.width * scale, originalSize.height * scale);
// Scale the original image to match the new size.
UIGraphicsBeginImageContext(newSize);
[original drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *compressedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return compressedImage;
}
Thanks to @Tuan Nguyen.
Solution 4
To complement @Tuan Nguyen, this is maybe the fastest and most elegant way to do that.
To link to John Muchow's post at iphonedevelopertips.com , adding a category to a UIImage is a very very handy way to scale in a very fast fashion. Just calling
UIImage *_image = [[[UIImage alloc] initWithData:SOME_NSDATA] scaleToSize:CGSizeMake(640.0,480.0)];
returns you a 640x480 representation image of your NSDATA ( that could be an online image ) without any more line of code.
Solution 5
Matt Gemmell's MGImageUtilities are very nice, resizing efficiently and with some effort-reducing methods.
joshholat
Updated on July 21, 2022Comments
-
joshholat almost 2 years
I'm currently uploading an image to a server using Imgur on iOS with the following code:
NSData* imageData = UIImagePNGRepresentation(image); NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString* fullPathToFile = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SBTempImage.png"]; [imageData writeToFile:fullPathToFile atomically:NO]; [uploadRequest setFile:fullPathToFile forKey:@"image"];
The code works fine when run in the simulator and uploading a file from the simulator's photo library because I'm on a fast ethernet connection. However, the same code times out on the iPhone when selecting an image taken with the iPhone. So, I tried it by saving a small image from the web and attempting to upload that, which worked.
This leads me to believe the large images taken by the iPhone are timing out over the somewhat slow 3G network. Is there any way to compress/resize the image from the iPhone before sending it?
-
Joshua Sullivan about 12 yearsThis changes the reported size of the scaled image, but does not actually change the image data. The data length of the NSData generated on the original and the scaled image is virtually identical.
-
Joshua Sullivan about 12 yearsThis is the solution that actually seems to work (image data size went from 145k to 30k).
-
Dexter almost 12 years"newSize" is CGSize eg. CGSize newSize = CGSizeMake(100.0f, 100.0f);
-
Michael about 11 yearsThis doesn't work! This shouldn't be the accepted answer! I just implemented it in my app only to find out that the image compressed to 25% of the original image size still has the same size in bytes than the original. I have no idea why there are so many upvotes or this non-working answer!
-
nembleton almost 11 yearsIt actually scales down the pixels. So it also reduces the size that the pic is taking. But it doesn't do a "recompression" per se. If that's what you are mentioning here.
-
DivineDesert almost 11 yearsGreat! Dont rush for compression techniques, easiest and good solution :)
-
Nuzhat Zari almost 11 yearsBut this will change the size of image, if I need to upload image to server with original specification, then this will not work, right?
-
mecabpazzo95 over 10 yearsdoesn't work. scales the image, but leaves the data full size.
-
Zorayr over 10 yearsAgain, does not work. Please remove/update this answer to not waste more time.
-
Nick Turner about 9 yearsIt doesn't change the file size because the Deep copy of an UIImage is a CGImage and resizing does not change the image. See the apple docs, to change the file size you create a new image with the scaled version. Learn what a pointer is. Let it also be known that scaling down then up will causing loss of the image and if you're using it for anything important it will look fuzzy later on. Compress it and using JPegCompress or whatever the function is called and send that.
-
scott over 8 yearsThis was exactly what i needed.
-
Chad about 8 yearsIt is usually helpful to elaborate on answers like this. Providing links to documentation, quotes from that documentation, as well as an explanation of why your code answers the question.
-
rcpfuchs about 8 yearsthis solution is nice, but it does not work for square images. because of originalSize.width > originalSize.height and originalSize.height > originalSize.width so better change one to >= :-)
-
Stephan Boner almost 8 yearsIs this the Size "newSize" the ImageSize in pixels?
-
Ver Nick over 5 years@FahimParkar +38 -70 LOL