Wydaje się, że to pytanie zostało uspokojone, ale w moim poszukiwaniu rozwiązania, które łatwiej byłoby zrozumieć (i napisane w Swift), doszedłem do tego (napisałem również: Jak przyciąć magię UIImage? )
Chciałem móc kadrować z regionu opartego na współczynniku kształtu i skalować do rozmiaru opartego na zewnętrznym zasięgu. Oto moja odmiana:
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
}
}
Jest kilka rzeczy, które uznałem za mylące, oddzielne obawy dotyczące kadrowania i zmiany rozmiaru. Kadrowanie jest obsługiwane przez początek prostokąta, który przekazujesz do drawInRect, a skalowanie jest obsługiwane przez część rozmiaru. W moim przypadku musiałem powiązać rozmiar prostownika przycinania na źródle z moim odbiciem wyjściowym o tym samym współczynniku kształtu. Współczynnik skali jest następnie wyprowadzany / wprowadzany i należy to zastosować do drawRect (przekazanego do drawInRect).
Jednym zastrzeżeniem jest to, że takie podejście skutecznie zakłada, że rysowany obraz jest większy niż kontekst obrazu. Nie testowałem tego, ale myślę, że możesz użyć tego kodu do obsługi kadrowania / powiększania, ale jawnie definiując parametr skali jako wyżej wspomniany parametr skali. Domyślnie UIKit stosuje mnożnik oparty na rozdzielczości ekranu.
Na koniec należy zauważyć, że to podejście UIKit jest wyższe niż podejście CoreGraphics / Quartz i Core Image i wydaje się, że rozwiązuje problemy z orientacją obrazu. Warto również wspomnieć, że jest dość szybki, po ImageIO, zgodnie z tym postem tutaj: http://nshipster.com/image-resizing/