UIImage Aspect Fit when using drawInRect? UIImage Aspect Fit when using drawInRect? ios ios

UIImage Aspect Fit when using drawInRect?


The math for that is a little bit hairy, but fortunately, here's a solution I prepared earlier:

- (UIImage *)imageScaledToSize:(CGSize)size{    //create drawing context    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);    //draw    [self drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];    //capture resultant image    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    return image;}- (UIImage *)imageScaledToFitSize:(CGSize)size{    //calculate rect    CGFloat aspect = self.size.width / self.size.height;    if (size.width / aspect <= size.height)    {        return [self imageScaledToSize:CGSizeMake(size.width, size.width / aspect)];    }    else    {        return [self imageScaledToSize:CGSizeMake(size.height * aspect, size.height)];    }}

The first function is equivalent to "scale to fill", the second (which calls the first) is equivalent to "aspect fit". These methods were written as a category on UIImage so to use them from within another class you'll need to tweak them by passing the image in as a second parameter (or just make a category on UIImage like I did).


You have to draw in the rect provided by

Swift:

func AVMakeRect(aspectRatio: CGSize, insideRect boundingRect: CGRect) -> CGRect

Objective-C:

CGRect AVMakeRectWithAspectRatioInsideRect(CGSize aspectRatio, CGRect boundingRect);

See doc

The aspect ratio is preserved and the drawing centred.

It works in absolutely all cases.


here's the solution

CGSize imageSize = yourImage.size;CGSize viewSize = CGSizeMake(450, 340); // size in which you want to drawfloat hfactor = imageSize.width / viewSize.width;float vfactor = imageSize.height / viewSize.height;float factor = fmax(hfactor, vfactor);// Divide the size by the greater of the vertical or horizontal shrinkage factorfloat newWidth = imageSize.width / factor;float newHeight = imageSize.height / factor;CGRect newRect = CGRectMake(xOffset,yOffset, newWidth, newHeight);[image drawInRect:newRect];

-- courtesy https://stackoverflow.com/a/1703210

another alternative for aspect fit

-(CGSize ) getImageSize :(CGSize )imgViewSize andActualImageSize:(CGSize )actualImageSize {     // imgViewSize = size of view in which image is to be drawn     // actualImageSize = size of image which is to be drawn     CGSize drawImageSize;     if (actualImageSize.height > actualImageSize.width) {        drawImageSize.height = imgViewSize.height;        drawImageSize.width = actualImageSize.width/actualImageSize.height * imgViewSize.height;     }else {        drawImageSize.width = imgViewSize.width;        drawImageSize.height = imgViewSize.width * actualImageSize.height /  actualImageSize.width;     }     return drawImageSize;}

Code for swift 3.0:

func getAspectFitFrame(sizeImgView:CGSize, sizeImage:CGSize) -> CGRect{    let imageSize:CGSize  = sizeImage    let viewSize:CGSize = sizeImgView    let hfactor : CGFloat = imageSize.width/viewSize.width    let vfactor : CGFloat = imageSize.height/viewSize.height    let factor : CGFloat = max(hfactor, vfactor)    // Divide the size by the greater of the vertical or horizontal shrinkage factor    let newWidth : CGFloat = imageSize.width / factor    let newHeight : CGFloat = imageSize.height / factor    var x:CGFloat = 0.0    var y:CGFloat = 0.0    if newWidth > newHeight{        y = (sizeImgView.height - newHeight)/2    }    if newHeight > newWidth{        x = (sizeImgView.width - newWidth)/2    }    let newRect:CGRect = CGRect(x: x, y: y, width: newWidth, height: newHeight)    return newRect}