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}