Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to scale down a UIImage and make it crispy / sharp at the same time instead of blurry?

I need to scale down an image, but in a sharp way. In Photoshop for example there are the image size reduction options "Bicubic Smoother" (blurry) and "Bicubic Sharper".

Is this image downscaling algorithm open sourced or documented somewhere or does the SDK offer methods to do this?

like image 675
Proud Member Avatar asked May 26 '11 15:05

Proud Member


People also ask

How do I change the size of my Uiimageview?

Here is a simple way: UIImage * image = [UIImage imageNamed:@"image"]; CGSize sacleSize = CGSizeMake(10, 10); UIGraphicsBeginImageContextWithOptions(sacleSize, NO, 0.0); [image drawInRect:CGRectMake(0, 0, sacleSize.

How do I make an image smaller in Xcode?

Assuming that you are referring to the layout in storyboard/IB. To get the native size of the image just select the image and press Command + = on the keyboard. the to re-size it proportionally select the corner and hold down the shift key when you re-size it.


2 Answers

Merely using imageWithCGImage is not sufficient. It will scale, but the result will be blurry and suboptimal whether scaling up or down.

If you want to get the aliasing right and get rid of the "jaggies" you need something like this: http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/.

My working test code looks something like this, which is Trevor's solution with one small adjustment to work with my transparent PNGs:

- (UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize {     CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));     CGImageRef imageRef = image.CGImage;      UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);     CGContextRef context = UIGraphicsGetCurrentContext();      // Set the quality level to use when rescaling     CGContextSetInterpolationQuality(context, kCGInterpolationHigh);     CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);      CGContextConcatCTM(context, flipVertical);       // Draw into the context; this scales the image     CGContextDrawImage(context, newRect, imageRef);      // Get the resized image from the context and a UIImage     CGImageRef newImageRef = CGBitmapContextCreateImage(context);     UIImage *newImage = [UIImage imageWithCGImage:newImageRef];      CGImageRelease(newImageRef);     UIGraphicsEndImageContext();          return newImage; } 
like image 171
Dan Rosenstark Avatar answered Oct 09 '22 13:10

Dan Rosenstark


For those using Swift here is the accepted answer in Swift:

func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {     let newRect = CGRectIntegral(CGRectMake(0,0, newSize.width, newSize.height))     let imageRef = image.CGImage      UIGraphicsBeginImageContextWithOptions(newSize, false, 0)     let context = UIGraphicsGetCurrentContext()      // Set the quality level to use when rescaling     CGContextSetInterpolationQuality(context, kCGInterpolationHigh)     let flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height)      CGContextConcatCTM(context, flipVertical)     // Draw into the context; this scales the image     CGContextDrawImage(context, newRect, imageRef)      let newImageRef = CGBitmapContextCreateImage(context) as CGImage     let newImage = UIImage(CGImage: newImageRef)      // Get the resized image from the context and a UIImage     UIGraphicsEndImageContext()      return newImage } 
like image 21
bzmw Avatar answered Oct 09 '22 12:10

bzmw