Я хотел иметь возможность обрезать область, основываясь на соотношении сторон, и масштабировать до размера, основанного на внешнем ограничивающем экстенте. Вот мой вариант:
import AVFoundation
import ImageIO
class Image {
class func crop(image:UIImage, source:CGRect, aspect:CGSize, outputExtent:CGSize) -> UIImage {
let sourceRect = AVMakeRectWithAspectRatioInsideRect(aspect, source)
let targetRect = AVMakeRectWithAspectRatioInsideRect(aspect, CGRect(origin: CGPointZero, size: outputExtent))
let opaque = true, deviceScale:CGFloat = 0.0 // use scale of device's main screen
UIGraphicsBeginImageContextWithOptions(targetRect.size, opaque, deviceScale)
let scale = max(
targetRect.size.width / sourceRect.size.width,
targetRect.size.height / sourceRect.size.height)
let drawRect = CGRect(origin: -sourceRect.origin * scale, size: image.size * scale)
image.drawInRect(drawRect)
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return scaledImage
}
}
Есть пара вещей, которые я нахожу запутанными, отдельные проблемы обрезки и изменения размера. Обрезка обрабатывается с началом координат прямоугольника, который вы передаете drawInRect, а масштабирование обрабатывается частью размера. В моем случае мне нужно было связать размер прямоугольника обрезки на источнике с моим выходным прямоугольником с тем же соотношением сторон. Затем масштабный коэффициент выводится / вводится, и его необходимо применить к drawRect (передается в drawInRect).
Одно предостережение в том, что этот подход фактически предполагает, что изображение, которое вы рисуете, больше, чем контекст изображения. Я не проверял это, но я думаю, что вы можете использовать этот код для обработки кадрирования / масштабирования, но явно определив параметр масштаба как вышеупомянутый параметр масштаба. По умолчанию UIKit применяет множитель в зависимости от разрешения экрана.
Наконец, следует отметить, что этот подход UIKit имеет более высокий уровень, чем подходы CoreGraphics / Quartz и Core Image, и, похоже, решает проблемы ориентации изображения. Также стоит упомянуть, что это довольно быстро, второй после ImageIO, согласно этому посту здесь: http://nshipster.com/image-resizing/