Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize an image with drawInRect while maintaining the aspect ratio like Scale Aspect Fill?

Tags:

ios

swift

uiimage

I would like to resize an image with drawInRect method, but I would also like to maintain the right aspect ratio, while filling completely the given frame (as .ScaleAspectFill does for UIViewContentMode). Anyone has a ready answer for this?

Here is my code (pretty straightforward...):

func scaled100Image() -> UIImage {
    let newSize = CGSize(width: 100, height: 100)
    UIGraphicsBeginImageContext(newSize)
    self.pictures[0].drawInRect(CGRect(x: 0, y: 0, width: 100, height: 100))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}
like image 340
winterized Avatar asked May 29 '15 09:05

winterized


People also ask

How do I find my aspect ratio in Uiimage?

size. height * scaleFactor let newWidth = oldWidth * scaleFactor UIGraphicsBeginImageContext(CGSize(width:newWidth, height:newHeight)) sourceImage. draw(in: CGRect(x:0, y:0, width:newWidth, height:newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! }

How do you resize a photo proportionally?

If the Shift key is held down whilst moving the handle, then the proportions of the object will be preserved. For example, if I hold Shift and drag the bottom edge upwards to reduce the size by half, then the right edge will automatically move to the left to reduce the width of the object by the same amount.

What does resizable do in SwiftUI?

Sets the mode by which SwiftUI resizes an image to fit its space.


2 Answers

OK, so no ready-made answer... I wrote a swift extension for UIImage, feel free to use it if you need it.

Here it is:

extension UIImage {
    func drawInRectAspectFill(rect: CGRect) {
            let targetSize = rect.size
    if targetSize == .zero {
        self.draw(in: rect)
    }
    let widthRatio    = targetSize.width  / self.size.width
    let heightRatio   = targetSize.height / self.size.height
    let scalingFactor = max(widthRatio, heightRatio)
    let newSize = CGSize(width:  self.size.width  * scalingFactor,
                         height: self.size.height * scalingFactor)
    UIGraphicsBeginImageContext(targetSize)
    let origin = CGPoint(x: (targetSize.width  - newSize.width)  / 2,
                         y: (targetSize.height - newSize.height) / 2)
    self.draw(in: CGRect(origin: origin, size: newSize))
    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    scaledImage?.draw(in: rect)
    }
}

So in the example above, you use it like that:

self.pictures[0].drawInRectAspectFill(CGRect(x: 0, y: 0, width: 100, height: 100))
like image 96
winterized Avatar answered Sep 18 '22 00:09

winterized


The Objective-C version, if someone need it(Paste this code inside a UIIMage category):

- (void) drawInRectAspectFill:(CGRect) recto {

CGSize targetSize = recto.size;
if (targetSize.width <= CGSizeZero.width && targetSize.height <= CGSizeZero.height ) {
    return  [self drawInRect:recto];
}

float widthRatio = targetSize.width  / self.size.width;
float heightRatio   = targetSize.height / self.size.height;
float scalingFactor = fmax(widthRatio, heightRatio);
CGSize newSize = CGSizeMake(self.size.width  * scalingFactor, self.size.height * scalingFactor);

UIGraphicsBeginImageContext(targetSize);

CGPoint origin = CGPointMake((targetSize.width-newSize.width)/2,(targetSize.height - newSize.height) / 2);

[self drawInRect:CGRectMake(origin.x, origin.y, newSize.width, newSize.height)];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

[scaledImage drawInRect:recto];

}

like image 33
Totka Avatar answered Sep 22 '22 00:09

Totka