Ich habe in Swift eine ultimative Lösung für die Bildskalierung entwickelt.
Sie können die Größe des Bilds so ändern, dass es die angegebene Größe füllt, füllt oder anpasst.
Sie können das Bild an der Mitte oder an einer der vier Kanten und vier Ecken ausrichten.
Außerdem können Sie zusätzlichen Platz kürzen, der hinzugefügt wird, wenn die Seitenverhältnisse von Originalbild und Zielgröße nicht gleich sind.
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
}
}
Im Folgenden finden Sie Beispiele für die Anwendung dieser Lösung.
Das graue Rechteck ist die Größe des Zielseitenbilds. Blaue Kreise im hellblauen Rechteck sind das Bild (ich habe Kreise verwendet, weil es leicht zu erkennen ist, wenn es skaliert ist, ohne den Aspekt beizubehalten). Die hellorange Farbe markiert Bereiche, die beim Passieren zugeschnitten werden trim: true
.
Aspektanpassung vor und nach der Skalierung:
Ein weiteres Beispiel für die Aspektanpassung :
Aspektanpassung mit oberer Ausrichtung:
Aspektfüllung :
Füllen :
In meinen Beispielen habe ich Upscaling verwendet, weil es einfacher zu demonstrieren ist, aber die Lösung funktioniert auch für das Downscaling wie in Frage.
Für die JPEG-Komprimierung sollten Sie Folgendes verwenden:
let compressionQuality: CGFloat = 0.75 // adjust to change JPEG quality
if let data = UIImageJPEGRepresentation(image, compressionQuality) {
// ...
}
Sie können meinen Kern mit Xcode Spielplatz überprüfen .