Cette question semble avoir été mise au repos, mais dans ma quête d'une solution que je pourrais comprendre plus facilement (et écrite en Swift), j'y suis arrivé (également posté sur: Comment recadrer l'IUImage? )
Je voulais pouvoir recadrer à partir d'une région en fonction d'un rapport hauteur / largeur et redimensionner à une taille basée sur une étendue de délimitation externe. Voici ma variante:
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
}
}
Il y a quelques choses que j'ai trouvées déroutantes, les préoccupations distinctes du recadrage et du redimensionnement. Le recadrage est géré avec l'origine du rect que vous passez à drawInRect, et la mise à l'échelle est gérée par la partie de taille. Dans mon cas, je devais relier la taille du rect de recadrage sur la source, à mon rect de sortie du même rapport hauteur / largeur. Le facteur d'échelle est alors sortie / entrée, et cela doit être appliqué à drawRect (passé à drawInRect).
Une mise en garde est que cette approche suppose en fait que l'image que vous dessinez est plus grande que le contexte de l'image. Je n'ai pas testé cela, mais je pense que vous pouvez utiliser ce code pour gérer le recadrage / zoom, mais en définissant explicitement le paramètre d'échelle comme étant le paramètre d'échelle susmentionné. Par défaut, UIKit applique un multiplicateur basé sur la résolution de l'écran.
Enfin, il convient de noter que cette approche UIKit est de plus haut niveau que les approches CoreGraphics / Quartz et Core Image, et semble gérer les problèmes d'orientation de l'image. Il convient également de mentionner que c'est assez rapide, après ImageIO, selon ce post ici: http://nshipster.com/image-resizing/