Am dezvoltat o soluție finală pentru scalare a imaginii în Swift.
Puteți să-l utilizați pentru a redimensiona imaginea pentru a umple, aspectul umple sau aspectul se potrivesc dimensiunea specificată.
Puteți alinia imaginea la centru sau la oricare dintre cele patru margini și patru colțuri.
Și, de asemenea, puteți decupa spațiu suplimentar care se adaugă, dacă rapoarte de aspect ale imaginii originale și dimensiunea țintă nu sunt egale.
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
}
}
Există exemple de aplicare a acestei soluții de mai jos.
Dreptunghi gri este imaginea site - ului țintă vor fi redimensionate la. Cercuri albastre în dreptunghi albastru deschis este imaginea (am folosit cercuri , pentru că este ușor pentru a vedea când este scalate fără a păstra aspectul). Culoarea portocalie Lumina marchează zonele care vor fi eliminate dacă treci trim: true.
Aspect potrivesc înainte și după scalarea:

Un alt exemplu de fit aspect :

Aspect potrivesc cu aliniere sus:

Aspect de umplere :

Umple :

Am folosit Upscaling în exemplele mele pentru că este mai simplu de a demonstra, dar soluția funcționează și pentru ca în cauză downscaling.
Pentru compresia JPEG ar trebui să utilizați acest lucru:
let compressionQuality: CGFloat = 0.75 // adjust to change JPEG quality
if let data = UIImageJPEGRepresentation(image, compressionQuality) {
// ...
}
Puteți verifica afară meu GIST cu Xcode un loc de joacă.