Этот вопрос, кажется, был поставлен на покой, но в моем поиске решения, которое я мог бы более легко понять (и написанного на Swift), я пришел к этому (также опубликованному по адресу: Как обрезать UIImage? )
Я хотел быть в состоянии обрезать из области, основанной на соотношении сторон, и масштабировать до размера, основанного на внешнем ограничивающем экстенте. Вот мой вариант:
import AVFoundation
import ImageIO
class Image {
class func crop(image:UIImage, crop 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/