Mustafa
Mustafa

Reputation: 20564

Reduce UIImage size to a manageable size (reduce bytes)

I want to reduce the number of bytes of an image captured by the device, since i believe the _imageScaledToSize does not reduce the number of bytes of the picture (or does it?) - i want to store a thumbnail of the image in a local dictionary object and can't afford to put full size images in the dictionary. Any idea?

Upvotes: 9

Views: 22841

Answers (5)

user2067021
user2067021

Reputation: 4529

UIImageJPEGRepresentation does the trick but I find that using the ImageIO framework often gets significantly better compression results for the same quality setting. It may be slower, but depending on your use case this may not be an issue.

(Code adapted for NSData from this blog post by Zachary West).

#import <MobileCoreServices/MobileCoreServices.h>
#import <ImageIO/ImageIO.h>

...

+ (NSData*)JPEGDataFromImage:(UIImage*)image quality:(double)quality
{
    CFMutableDataRef outputImageDataRef = CFDataCreateMutable(kCFAllocatorDefault, 0);
    CGImageDestinationRef imageDestinationRef = CGImageDestinationCreateWithData(outputImageDataRef, kUTTypeJPEG, 1, NULL);

    NSDictionary* properties = @{
        (__bridge NSString*)kCGImageDestinationLossyCompressionQuality: @(quality)
    };
    CGImageDestinationSetProperties(imageDestinationRef, (__bridge CFDictionaryRef)properties);

    CGImageDestinationAddImage(imageDestinationRef, image.CGImage, NULL);

    CGImageDestinationFinalize(imageDestinationRef);

    CFRelease(imageDestinationRef);

    NSData* imageData = CFBridgingRelease(outputImageDataRef);
    return imageData;
}

Upvotes: 0

Brad Larson
Brad Larson

Reputation: 170319

If you wish to simply compress your UIImage, you can use

NSData *dataForPNGFile = UIImagePNGRepresentation(yourImage);

to generate an NSData version of your image encoded as a PNG (easily inserted into an NSDictionary or written to disk), or you can use

NSData *dataForPNGFile = UIImageJPEGRepresentation(yourImage, 0.9f);

to do the same, only in a JPEG format. The second parameter is the image quality of the JPEG. Both of these should produce images that are smaller, memory-wise, than your UIImage.

Resizing a UIImage to create a smaller thumbnail (pixels-wise) using published methods is a little trickier. _imageScaledToSize is from the private API, and I'd highly recommend you not use it. For a means that works within the documented methods, see this post.

Upvotes: 23

radesix
radesix

Reputation: 6262

I ran into this problem the other day and did quite a bit of research. I found an awesome solution complete with code here:

http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

Upvotes: 10

mmr
mmr

Reputation: 14919

When you say 'physical size', are you talking about a print? Because you can just change the printer page size.

Are you talking about the number of pixels used to capture the image? As in, if you have a pixel array of 3000x2000, and you only want 150x150, then you can crop the images. At the time of capture, if you have a scientific imager, then you can just set the area that will be captured. The camera driver would include instructions for that. If you want to capture 3000x2000 in 1500x1000, you can try to bin the image, if that's what you need.

Or, you can use resampling post-capture in order to make the image smaller. One such algorithm is bicubic resampling, also linear resampling-- there are many variations.

I'm thinking this last is what you're most interested in... in which case, check out this Wikipedia page on the algorithm. Or, you can go to FreeImage and get a library that will read in the image and can also resize images.

Upvotes: 0

Mike Abdullah
Mike Abdullah

Reputation: 15003

You need to draw the image into a graphics context at a smaller size. Then, release the original image.

Upvotes: 1

Related Questions