Diese Frage scheint zur Ruhe gekommen zu sein, aber auf meiner Suche nach einer Lösung, die ich leichter verstehen konnte (und die in Swift geschrieben wurde), bin ich zu dieser Frage gekommen (auch gepostet unter: Wie man das UIImage beschneidet? )
Ich wollte in der Lage sein, aus einer Region basierend auf einem Seitenverhältnis zu beschneiden und auf eine Größe zu skalieren, die auf einem Ausmaß der äußeren Begrenzung basiert. Hier ist meine Variation:
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
}
}
Es gibt ein paar Dinge, die ich verwirrend fand, die getrennten Probleme beim Zuschneiden und Ändern der Größe. Das Zuschneiden wird mit dem Ursprung des Rect behandelt, das Sie an drawInRect übergeben, und das Skalieren wird durch den Größenbereich behandelt. In meinem Fall musste ich die Größe des Zuschneide-Rechtecks auf der Quelle mit meinem Ausgangs-Rechteck mit demselben Seitenverhältnis in Beziehung setzen. Der Skalierungsfaktor wird dann ausgegeben / eingegeben und muss auf drawRect angewendet werden (an drawInRect übergeben).
Eine Einschränkung besteht darin, dass bei diesem Ansatz effektiv davon ausgegangen wird, dass das von Ihnen gezeichnete Bild größer als der Bildkontext ist. Ich habe dies nicht getestet, aber ich denke, Sie können diesen Code zum Zuschneiden / Zoomen verwenden, aber den Skalierungsparameter explizit als den oben genannten Skalierungsparameter definieren. Standardmäßig wendet UIKit einen Multiplikator an, der auf der Bildschirmauflösung basiert.
Schließlich sollte angemerkt werden, dass dieser UIKit-Ansatz höher ist als die CoreGraphics / Quartz- und Core Image-Ansätze und Probleme mit der Bildorientierung zu behandeln scheint. Es ist auch erwähnenswert, dass es nach ImageIO ziemlich schnell ist, laut diesem Beitrag hier: http://nshipster.com/image-resizing/