views:

562

answers:

5

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?

A: 

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;
}
Marc W
+6  A: 

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;
}
mmc
so what happens if the ratio is different? what will drawInRect do? Say original is 2000x1000 and I passed in 480x480
erotsppa
From the developer docs on UIImage - "Draws the entire image in the specified rectangle, scaling it as needed to fit."
mmc
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
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
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
A: 

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

fbrereto
A: 
tmpImage = [[UIImage imageNamed:imageName] _imageScaledToSize:CGSizeMake(80.0f, 80.0f) interpolationQuality:1];

undocumented API, but it's what is internally used, so more likely to work as intended. Credits to this.

luvieere
+1  A: 

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.

JosephH