Saya mengembangkan solusi pamungkas untuk penskalaan gambar di Swift.
Anda dapat menggunakannya untuk mengubah ukuran gambar untuk diisi, mengisi aspek, atau menyesuaikan aspek ukuran yang ditentukan.
Anda dapat meratakan gambar ke tengah atau salah satu dari empat tepi dan empat sudut.
Dan juga Anda dapat memangkas ruang ekstra yang ditambahkan jika rasio aspek gambar asli dan ukuran target tidak sama.
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
}
}
Ada contoh penerapan solusi ini di bawah.
Persegi panjang abu-abu adalah gambar situs target yang akan diubah ukurannya menjadi. Lingkaran biru dalam persegi panjang biru muda adalah gambarnya (saya menggunakan lingkaran karena mudah dilihat saat diskalakan tanpa mempertahankan aspek). Warna oranye terang menandai area yang akan dipangkas jika Anda lewat trim: true
.
Aspek pas sebelum dan sesudah penskalaan:
Contoh lain dari aspek kesesuaian :
Aspek pas dengan perataan atas:
Isi aspek :
Isi :
Saya menggunakan upscaling dalam contoh saya karena lebih mudah untuk didemonstrasikan tetapi solusi juga berfungsi untuk downscaling seperti yang dipermasalahkan.
Untuk kompresi JPEG Anda harus menggunakan ini:
let compressionQuality: CGFloat = 0.75 // adjust to change JPEG quality
if let data = UIImageJPEGRepresentation(image, compressionQuality) {
// ...
}
Anda dapat melihat inti saya dengan taman bermain Xcode.