Is there any code or library out there that can help me scale down an image? If you take a picture with the iPhone, it is something like 2000x1000 pixels which is not very network friendly. I want to scale it down to say 480x320. Any hints?
4 Answers
This is what I am using. Works well. I'll definitely be watching this question to see if anyone has anything better/faster. I just added the below to a category on UIimage
.
+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

- 17,354
- 2
- 34
- 52
-
so what happens if the ratio is different? what will drawInRect do? Say original is 2000x1000 and I passed in 480x480 – erotsppa Oct 15 '09 at 17:56
-
From the developer docs on UIImage - "Draws the entire image in the specified rectangle, scaling it as needed to fit." – mmc Oct 15 '09 at 19:25
-
This method takes a LONG time to run, sometimes more than a minute. I'm scaling down the picture taken by the iPhone 3GS camera to 500x500. Why is that I wonder? – erotsppa Oct 16 '09 at 14:43
-
I have noticed that it takes a while (but for me, it's 4-8 seconds, rather than over minute) which was why I was watching the other answers... I intend to benchmark them. – mmc Oct 16 '09 at 16:43
-
Why is is that it takes < 1 second to scale a picture into a UIImageView, but so many seconds to scale it into another UIImage? – erotsppa Oct 16 '09 at 17:32
See http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/ - this has a set of code you can download as well as some descriptions.
If speed is a worry, you can experiment with using CGContextSetInterpolationQuality to set a lower interpolation quality than the default.

- 37,173
- 19
- 130
- 154
Please note, this is NOT my code. I did a little digging and found it here. I figured you'd have to drop into the CoreGraphics layer, but wasn't quite sure of the specifics. This should work. Just be careful about managing your memory.
// ==============================================================
// resizedImage
// ==============================================================
// Return a scaled down copy of the image.
UIImage* resizedImage(UIImage *inImage, CGRect thumbRect)
{
CGImageRef imageRef = [inImage CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
// There's a wierdness with kCGImageAlphaNone and CGBitmapContextCreate
// see Supported Pixel Formats in the Quartz 2D Programming Guide
// Creating a Bitmap Graphics Context section
// only RGB 8 bit images with alpha of kCGImageAlphaNoneSkipFirst, kCGImageAlphaNoneSkipLast, kCGImageAlphaPremultipliedFirst,
// and kCGImageAlphaPremultipliedLast, with a few other oddball image kinds are supported
// The images on input here are likely to be png or jpeg files
if (alphaInfo == kCGImageAlphaNone)
alphaInfo = kCGImageAlphaNoneSkipLast;
// Build a bitmap context that's the size of the thumbRect
CGContextRef bitmap = CGBitmapContextCreate(
NULL,
thumbRect.size.width, // width
thumbRect.size.height, // height
CGImageGetBitsPerComponent(imageRef), // really needs to always be 8
4 * thumbRect.size.width, // rowbytes
CGImageGetColorSpace(imageRef),
alphaInfo
);
// Draw into the context, this scales the image
CGContextDrawImage(bitmap, thumbRect, imageRef);
// Get an image from the context and a UIImage
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage* result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap); // ok if NULL
CGImageRelease(ref);
return result;
}

- 19,083
- 4
- 59
- 71
Please see the solution I posted to this question. The question involves rotating an image 90 degrees instead of scaling it, but the premise is the same (it's just the matrix transformation that is different).