Це питання, здається, було покладено спокою, але в моєму прагненні рішення, яке я міг би легше зрозуміти (і написане в 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
}
}
Є кілька речей, які я вважаю заплутаними, окремі проблеми з обрізанням та зміною розміру. Обрізання обробляється з початком прямої прямої лінії, яку ви передаєте малюваннюInRect, а масштабування обробляється за розміром. У моєму випадку мені потрібно було співвідносити розмір прямої обрізки на джерелі, до моєї вихідної прямої з тим же співвідношенням сторін. Тоді коефіцієнт масштабу - це вихід / вхід, і це потрібно застосувати до drawRect (передано до drawInRect).
Одне застереження полягає в тому, що цей підхід ефективно передбачає, що зображення, яке ви малюєте, більше, ніж контекст зображення. Я цього не перевіряв, але думаю, що ви можете використовувати цей код для обробки обрізання / масштабування, але чітко визначаючи параметр масштабу як згаданий параметр масштабу. За замовчуванням UIKit застосовує множник на основі роздільної здатності екрана.
Нарешті, слід зазначити, що цей підхід UIKit вищий рівень, ніж підходи CoreGraphics / Quartz та Core Image, і, здається, вирішує проблеми орієнтації на зображення. Варто також зазначити, що це досить швидко, поступаючись ImageIO, згідно з цим повідомленням тут: http://nshipster.com/image-resizing/