Измените размер изображения с помощью drawInRect, сохраняя пропорции, такие как Scale Aspect Fill?

Я хотел бы изменить размер изображения с помощью метода drawInRect, но я также хотел бы поддерживать правильное соотношение сторон, полностью заполняя данный кадр (как .ScaleAspectFill для UIViewContentMode). У кого есть готовый ответ для этого?

Вот мой код (довольно простой...):

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
}

Ответ 1

Хорошо, поэтому нет готового ответа... Я написал быстрое расширение для UIImage, не стесняйтесь использовать его, если вам это нужно.

Вот он:

extension UIImage {
    func drawInRectAspectFill(rect: CGRect) {
        let targetSize = rect.size
        if targetSize == CGSizeZero {
            return self.drawInRect(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.drawInRect(CGRect(origin: origin, size: newSize))
        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        scaledImage.drawInRect(rect)
    }
}

Итак, в приведенном выше примере вы используете его так:

self.pictures[0].drawInRectAspectFill(CGRect(x: 0, y: 0, width: 100, height: 100))

Ответ 2

Версия Objective-C, если кому-то это нужно (вставьте этот код в категорию UIIMage):

- (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];

}