About the author

Related Articles

18 Comments

  1. 1
    Rogerio

    Rogerio Chaves

    Here’s the Swift version of Paul Lynch’s answer

    func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
        image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
        let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
    

    Swift 3.0 version:

    func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
        image.draw(in: CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: newSize.width, height: newSize.height)))
        let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }
    
    Reply
  2. 2
    tiritea@email.null'

    tiritea

    [cf Chris] To resize to a desired size:

    UIImage *after = [UIImage imageWithCGImage:before.CGImage
                                         scale:CGImageGetHeight(before.CGImage)/DESIREDHEIGHT
                                   orientation:UIImageOrientationUp];
    

    or, equivalently, substitute CGImageGetWidth(...)/DESIREDWIDTH

    Reply
  3. 3
    Beslan

    Beslan Tularov

    use this extension

    extension UIImage {
        public func resize(size:CGSize, completionHandler:(resizedImage:UIImage, data:NSData?)->()) {
            dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in
                let newSize:CGSize = size
                let rect = CGRectMake(0, 0, newSize.width, newSize.height)
                UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
                self.drawInRect(rect)
                let newImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                let imageData = UIImageJPEGRepresentation(newImage, 0.5)
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    completionHandler(resizedImage: newImage, data:imageData)
                })
            })
        }
    }
    
    Reply
  4. 4
    ashwini

    ashwini

     func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage 
    {
            let scale = newWidth / image.size.width
            let newHeight = image.size.height * scale
            UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
            image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage
    }
    
    Reply
  5. 5
    Phil@email.null'

    Phil

    Swift 2.0 :

    let image = UIImage(named: "imageName")
    let newSize = CGSize(width: 10, height: 10)
    
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
    image?.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
    let imageResized = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    Reply
  6. 6
    Intentss@email.null'

    Intentss

    Rogerio Chaves answer as a swift extension

    extension UIImage{
        func scaledToSize(size: CGSize) -> UIImage{
            UIGraphicsBeginImageContextWithOptions(size, false, 0.0);
            self.drawInRect(CGRectMake(0, 0, size.width, size.height))
            let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage
        }
    }
    
    Reply
  7. 7
    Chris@email.null'

    Chris

    Why so complicated? I think using system API can achieve the same result:

    UIImage *largeImage;
    CGFloat ratio = 0.4; // you want to get a new image that is 40% the size of large image.
    UIImage *newImage = [UIImage imageWithCGImage:largeImage.CGImage
                                            scale:1/ratio
                                      orientation:largeImage.imageOrientation];
    // notice the second argument, it is 1/ratio, not ratio.
    

    The only gotcha is you should pass inverse of target ratio as the second argument, as according to the document the second parameter specifies the ratio of original image compared to the new scaled one.

    Reply
  8. 8
    iWasRobbed@email.null'

    iWasRobbed

    I’ve also seen this done as well (which I use on UIButtons for Normal and Selected state since buttons don’t resize to fit). Credit goes to whoever the original author was.

    First make an empty .h and .m file called UIImageResizing.h and UIImageResizing.m

    // Put this in UIImageResizing.h
    @interface UIImage (Resize)
    - (UIImage*)scaleToSize:(CGSize)size;
    @end
    
    // Put this in UIImageResizing.m
    @implementation UIImage (Resize)
    
    - (UIImage*)scaleToSize:(CGSize)size {
    UIGraphicsBeginImageContext(size);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0.0, size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage);
    
    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return scaledImage;
    }
    
    @end
    

    Include that .h file in whatever .m file you’re going to use the function in and then call it like this:

    UIImage* image = [UIImage imageNamed:@"largeImage.png"];
    UIImage* smallImage = [image scaleToSize:CGSizeMake(100.0f,100.0f)];
    
    Reply
  9. 9
    Dan

    Dan Rosenstark

    Here my somewhat-verbose Swift code

    func scaleImage(image:UIImage,  toSize:CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(toSize, false, 0.0);
    
        let aspectRatioAwareSize = self.aspectRatioAwareSize(image.size, boxSize: toSize, useLetterBox: false)
    
    
        let leftMargin = (toSize.width - aspectRatioAwareSize.width) * 0.5
        let topMargin = (toSize.height - aspectRatioAwareSize.height) * 0.5
    
    
        image.drawInRect(CGRectMake(leftMargin, topMargin, aspectRatioAwareSize.width , aspectRatioAwareSize.height))
        let retVal = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return retVal
    }
    
    func aspectRatioAwareSize(imageSize: CGSize, boxSize: CGSize, useLetterBox: Bool) -> CGSize {
        // aspect ratio aware size
        // http://stackoverflow.com/a/6565988/8047
        let wi = imageSize.width
        let hi = imageSize.height
        let ws = boxSize.width
        let hs = boxSize.height
    
        let ri = wi/hi
        let rs = ws/hs
    
        let retVal : CGSize
        // use the else at your own risk: it seems to work, but I don't know 
        // the math
        if (useLetterBox) {
            retVal = rs > ri ? CGSizeMake(wi * hs / hi, hs) : CGSizeMake(ws, hi * ws / wi)
        } else {
            retVal = rs < ri ? CGSizeMake(wi * hs / hi, hs) : CGSizeMake(ws, hi * ws / wi)
        }
    
        return retVal
    }
    
    Reply
  10. 10
    aubykhan@email.null'

    aubykhan

    I found a category for UIImage in Apple’s own examples which does the same trick. Here’s the link: https://developer.apple.com/library/ios/samplecode/sc2273/Listings/AirDropSample_UIImage_Resize_m.html.

    You’ll just have to change the call:

    UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);
    

    in imageWithImage:scaledToSize:inRect: with:

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 2.0);
    

    In order to consider the alpha channel in the image.

    Reply
  11. 11
    Scott

    Scott Means

    Here’s a modification of the category written by iWasRobbed above. It keeps the aspect ratio of the original image instead of distorting it.

    - (UIImage*)scaleToSizeKeepAspect:(CGSize)size {
        UIGraphicsBeginImageContext(size);
    
        CGFloat ws = size.width/self.size.width;
        CGFloat hs = size.height/self.size.height;
    
        if (ws > hs) {
            ws = hs/ws;
            hs = 1.0;
        } else {
            hs = ws/hs;
            ws = 1.0;
        }
    
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context, 0.0, size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
    
        CGContextDrawImage(context, CGRectMake(size.width/2-(size.width*ws)/2,
            size.height/2-(size.height*hs)/2, size.width*ws,
            size.height*hs), self.CGImage);
    
        UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return scaledImage;
    }
    
    Reply
  12. 12
    asmad@email.null'

    asmad

    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.width, sacleSize.height)];
        UIImage * resizedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    

    resizedImage is a new image.

    Reply
  13. 13
    Paul

    Paul Lynch

    The simplest way is to set the frame of your UIImageView and set the contentMode to one of the resizing options.

    Or you can use this utility method, if you actually need to resize an image:

    + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
        //UIGraphicsBeginImageContext(newSize);
        // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
        // Pass 1.0 to force exact pixel size.
        UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
        [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
        UIGraphicsEndImageContext();
        return newImage;
    }
    

    Example usage:

    #import "MYUtil.h"
    …
    UIImage *myIcon = [MYUtil imageWithImage:myUIImageInstance scaledToSize:CGSizeMake(20, 20)];
    
    Reply
  14. 14
    sanmai@email.null'

    sanmai

    If you just want an image smaller and don’t care about exact size:

    + (UIImage *)imageWithImage:(UIImage *)image scaledToScale:(CGFloat)scale
    {
        UIGraphicsBeginImageContextWithOptions(self.size, YES, scale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
        [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }
    

    Setting scale to 0.25f will give you a 816 by 612 image from a 8MP camera.

    Here’s a category UIImage+Scale for those who needs one.

    Reply
  15. 15
    Vlad

    Vlad Andersen

    If you want to make a thumbnail of a UIImage (with proportional resizing or maybe some cropping involved), check out UIImage+Resize category that allows you to use concise, ImageMagick-like syntax:

    UIImage* squareImage       = [image resizedImageByMagick: @"320x320#"];
    
    Reply
  16. 16
    TechZen@email.null'

    TechZen

    Trevor Howard has some UIImage categories that handle resize quite nicely. If nothing else you can use the code as examples.

    Note: As of iOS 5.1, this answer maybe invalid. See comment below.

    Reply
  17. 17
    malhal@email.null'

    malhal

    This improvement to Paul’s code will give you a sharp high res image on an iPhone with a retina display. Otherwise when scaling down it’s blurry.

    + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        if ([[UIScreen mainScreen] scale] == 2.0) {
            UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);
        } else {
            UIGraphicsBeginImageContext(newSize);
        }
    } else {
        UIGraphicsBeginImageContext(newSize);
    }
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
    }
    
    Reply
  18. 18
    wossoneri@email.null'

    wossoneri

    @Paul Lynch’s answer is great, but it would change the image ratio.
    if you don`t want to change the image ratio, and still want the new image fit for new size, try this.

    + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    
    // calculate a new size which ratio is same to original image
    CGFloat ratioW = image.size.width / newSize.width;
    CGFloat ratioH = image.size.height / newSize.height;
    
    CGFloat ratio = image.size.width / image.size.height;
    
    CGSize showSize = CGSizeZero;
    if (ratioW > 1 && ratioH > 1) { 
    
        if (ratioW > ratioH) { 
            showSize.width = newSize.width;
            showSize.height = showSize.width / ratio;
        } else {
            showSize.height = newSize.height;
            showSize.width = showSize.height * ratio;
        }
    
    } else if (ratioW > 1) {
    
        showSize.width = showSize.width;
        showSize.height = showSize.width / ratio;
    
    } else if (ratioH > 1) {
    
        showSize.height = showSize.height;
        showSize.width = showSize.height * ratio;
    
    }
    
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(showSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, showSize.width, showSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;}
    
    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2017 SolutionMmyself.com