J'ai développé une solution ultime pour mise à l'échelle de l'image dans Swift.
Vous pouvez l'utiliser pour redimensionner l'image pour remplir, remplir aspect ou aspect adapter la taille spécifiée.
Vous pouvez aligner l'image au centre ou l'un des quatre bords et quatre angles.
Et vous pouvez également rogner l'espace supplémentaire qui est ajouté si des rapports d'aspect de l'image d'origine et la taille de la cible ne sont pas égaux.
enum UIImageAlignment {
case Center, Left, Top, Right, Bottom, TopLeft, BottomRight, BottomLeft, TopRight
}
enum UIImageScaleMode {
case Fill,
AspectFill,
AspectFit(UIImageAlignment)
}
extension UIImage {
func scaleImage(width width: CGFloat? = nil, height: CGFloat? = nil, scaleMode: UIImageScaleMode = .AspectFit(.Center), trim: Bool = false) -> UIImage {
let preWidthScale = width.map { $0 / size.width }
let preHeightScale = height.map { $0 / size.height }
var widthScale = preWidthScale ?? preHeightScale ?? 1
var heightScale = preHeightScale ?? widthScale
switch scaleMode {
case .AspectFit(_):
let scale = min(widthScale, heightScale)
widthScale = scale
heightScale = scale
case .AspectFill:
let scale = max(widthScale, heightScale)
widthScale = scale
heightScale = scale
default:
break
}
let newWidth = size.width * widthScale
let newHeight = size.height * heightScale
let canvasWidth = trim ? newWidth : (width ?? newWidth)
let canvasHeight = trim ? newHeight : (height ?? newHeight)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(canvasWidth, canvasHeight), false, 0)
var originX: CGFloat = 0
var originY: CGFloat = 0
switch scaleMode {
case .AspectFit(let alignment):
switch alignment {
case .Center:
originX = (canvasWidth - newWidth) / 2
originY = (canvasHeight - newHeight) / 2
case .Top:
originX = (canvasWidth - newWidth) / 2
case .Left:
originY = (canvasHeight - newHeight) / 2
case .Bottom:
originX = (canvasWidth - newWidth) / 2
originY = canvasHeight - newHeight
case .Right:
originX = canvasWidth - newWidth
originY = (canvasHeight - newHeight) / 2
case .TopLeft:
break
case .TopRight:
originX = canvasWidth - newWidth
case .BottomLeft:
originY = canvasHeight - newHeight
case .BottomRight:
originX = canvasWidth - newWidth
originY = canvasHeight - newHeight
}
default:
break
}
self.drawInRect(CGRectMake(originX, originY, newWidth, newHeight))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Il existe des exemples d'application de cette solution ci-dessous.
Le rectangle gris est l' image cible du site sera redimensionnée à. Les cercles bleus dans le rectangle bleu clair est l'image (je les cercles parce qu'il est facile de voir quand il est mis à l' échelle sans aspect préservation). Marque la lumière couleur orange des zones qui seront rognées si vous passez trim: true.
Aspect adapter avant et après mise à l' échelle:

Un autre exemple d' aspect en forme :

Aspect correspond à l' alignement du haut:

Remplissage Aspect :

remplir :

Je upscaling dans mes exemples, car il est plus simple de démontrer, mais la solution fonctionne aussi pour downscaling comme question.
Pour la compression JPEG, vous devez utiliser ceci:
let compressionQuality: CGFloat = 0.75 // adjust to change JPEG quality
if let data = UIImageJPEGRepresentation(image, compressionQuality) {
// ...
}
Vous pouvez consulter mon point essentiel avec aire de jeux Xcode.