How to compress/resize image on iOS before uploading to a server?

97,970

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.

Share:
97,970
joshholat
Author by

joshholat

Updated on July 21, 2022

Comments

  • joshholat
    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
    Joshua Sullivan about 12 years
    This 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
    Joshua Sullivan about 12 years
    This is the solution that actually seems to work (image data size went from 145k to 30k).
  • Dexter
    Dexter almost 12 years
    "newSize" is CGSize eg. CGSize newSize = CGSizeMake(100.0f, 100.0f);
  • Michael
    Michael about 11 years
    This 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
    nembleton almost 11 years
    It 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
    DivineDesert almost 11 years
    Great! Dont rush for compression techniques, easiest and good solution :)
  • Nuzhat Zari
    Nuzhat Zari almost 11 years
    But 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
    mecabpazzo95 over 10 years
    doesn't work. scales the image, but leaves the data full size.
  • Zorayr
    Zorayr over 10 years
    Again, does not work. Please remove/update this answer to not waste more time.
  • Nick Turner
    Nick Turner about 9 years
    It 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
    scott over 8 years
    This was exactly what i needed.
  • Chad
    Chad about 8 years
    It 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
    rcpfuchs about 8 years
    this 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
    Stephan Boner almost 8 years
    Is this the Size "newSize" the ImageSize in pixels?
  • Ver Nick
    Ver Nick over 5 years
    @FahimParkar +38 -70 LOL