Essa questão parece ter sido resolvida, mas na minha busca por uma solução que eu pudesse entender mais facilmente (e escrita em Swift), cheguei a isso (também publicado em: Como cortar a UIImage? )
Eu queria poder cortar de uma região com base em uma proporção e dimensionar para um tamanho com base em uma extensão delimitadora externa. Aqui está a minha variação:
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
}
}
Achei algumas coisas confusas, as preocupações separadas de cortar e redimensionar. O corte é tratado com a origem do rect que você passa para drawInRect, e o dimensionamento é tratado pela parte do tamanho. No meu caso, eu precisava relacionar o tamanho do reto de corte na origem, ao meu ret de saída da mesma proporção. O fator de escala é então enviado / recebido, e isso precisa ser aplicado ao drawRect (passado para drawInRect).
Uma ressalva é que essa abordagem assume efetivamente que a imagem que você está desenhando é maior que o contexto da imagem. Não testei isso, mas acho que você pode usar esse código para lidar com o corte / zoom, mas definindo explicitamente o parâmetro de escala como o parâmetro de escala acima mencionado. Por padrão, o UIKit aplica um multiplicador com base na resolução da tela.
Por fim, deve-se notar que essa abordagem do UIKit é de nível superior às abordagens CoreGraphics / Quartz e Core Image e parece lidar com problemas de orientação da imagem. Também vale ressaltar que é bastante rápido, segundo o ImageIO, de acordo com este post aqui: http://nshipster.com/image-resizing/