Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to scale down an image in iOS, anti-aliased but not soft?

I have tried the UIImage+Resize category that's popular, and with varying interpolation settings. I have tried scaling via CG methods, and CIFilters. However, I can never get an image downsized that does not either look slightly soft in focus, nor full of jagged artifacts. Is there another solution, or a third party library, which would let me get a very crisp image?

It must be possible on the iPhone, because for instance the Photos app will show a crisp image even when pinching to scale it down.

like image 295
akaru Avatar asked Feb 02 '12 17:02

akaru


2 Answers

You said CG, but did not specify your approach.

Using drawing or bitmap context:

CGContextSetInterpolationQuality(gtx, kCGInterpolationHigh);
CGContextSetShouldAntialias(gtx, true); << default varies by context type
CGContextDrawImage(gtx, rect, image);

and make sure your views and their layers are not resizing the image again. I've had good results with this. It's possible other views are affecting your view or the context. If it does not look good, try it in isolation to sanity check whether or not something is distorting your view/image.

If you are drawing to a bitmap, then you create the bitmap with the target dimensions, then draw to that.

Ideally, you will maintain the aspect ratio.

Also note that this can be quite CPU intensive -- repeatedly drawing/scaling in HQ will cost a lot of time, so you may want to create a resized copy instead (using CGBitmapContext).

like image 78
justin Avatar answered Sep 19 '22 10:09

justin


Here is the Routine that I wrote to do this. There is a bit of soft focus, though depending on how far you are scaling the original image its not too bad. I'm scaling programatic Screen Shot Images.

- (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {

    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}
like image 33
scooter133 Avatar answered Sep 20 '22 10:09

scooter133