この質問は解決されたようですが、もっと簡単に理解できる(そして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に渡されます)。
注意点の1つは、このアプローチでは、描画しているイメージがイメージコンテキストよりも大きいと想定していることです。私はこれをテストしていませんが、このコードを使用してクロッピング/ズームを処理できますが、前述のスケールパラメーターになるようにスケールパラメーターを明示的に定義します。デフォルトでは、UIKitは画面解像度に基づいて乗数を適用します。
最後に、このUIKitアプローチはCoreGraphics / QuartzおよびCore Imageアプローチよりもレベルが高く、画像の向きの問題を処理しているようです。この投稿によると、ImageIOに次ぐ、かなり高速であることにも言及する価値があります。http://nshipster.com/image-resizing/