我正在寻找通过调整图像大小而不是进一步压缩来减小 PNG 文件的文件大小的方法。
这里有很多示例代码通过将 UIImage 转换为 JPEG 来压缩 UIImage
像这样
extension UIImage {
func resized(withPercentage percentage: CGFloat, isOpaque: Bool = true) -> UIImage? {
let canvas = CGSize(width: size.width * percentage, height: size.height * percentage)
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: canvas, format: format).image {
_ in draw(in: CGRect(origin: .zero, size: canvas))
}
}
func resized(toWidth width: CGFloat, isOpaque: Bool = true) -> UIImage? {
let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: canvas, format: format).image {
_ in draw(in: CGRect(origin: .zero, size: canvas))
}
}
}
此代码允许您选择一个尺寸来调整图像大小,但它不允许您控制文件大小。
这里是一个缩小到特定大小的例子,但是因为它使用 JPEG 数据,所以失去了透明度 在上传到 Parse as PFFile 之前如何压缩或减小图像的大小? (斯威夫特)
extension UIImage {
func resized(withPercentage percentage: CGFloat, isOpaque: Bool = true) -> UIImage? {
let canvas = CGSize(width: size.width * percentage, height: size.height * percentage)
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: canvas, format: format).image {
_ in draw(in: CGRect(origin: .zero, size: canvas))
}
}
func compress(to kb: Int, allowedMargin: CGFloat = 0.2) -> Data {
let bytes = kb * 1024
var compression: CGFloat = 1.0
let step: CGFloat = 0.05
var holderImage = self
var complete = false
while(!complete) {
if let data = holderImage.jpegData(compressionQuality: 1.0) {
let ratio = data.count / bytes
if data.count < Int(CGFloat(bytes) * (1 + allowedMargin)) {
complete = true
return data
} else {
let multiplier:CGFloat = CGFloat((ratio / 5) + 1)
compression -= (step * multiplier)
}
}
guard let newImage = holderImage.resized(withPercentage: compression) else { break }
holderImage = newImage
}
return Data()
}
}
我拥有的是 png 图像,其中我保留了透明度,同时将文件大小保持在 500k 以下(硬限制 - 因为服务器限制它)
我怎样才能快速做到这一点?
你可以像那样对你的图像进行下采样
extension UIImage {
var asSmallImage: UIImage? {
let sourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
guard let cgImage = self.cgImage else { return nil }
guard let imgData = cgImage.isPNG ? self.pngData() : self.jpegData(compressionQuality: 0.75) else { return nil }
guard let source = CGImageSourceCreateWithData(imgData as CFData, sourceOptions) else { return nil }
let downsampleOptions = [
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceThumbnailMaxPixelSize: 1_000,
] as CFDictionary
guard let cgImage = CGImageSourceCreateThumbnailAtIndex(source, 0, downsampleOptions) else { return nil }
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data, kUTTypeJPEG, 1, nil) else { return nil }
// Don't compress PNGs, they're too pretty
let destinationProperties = [kCGImageDestinationLossyCompressionQuality: cgImage.isPNG ? 1.0 : 0.75] as CFDictionary
CGImageDestinationAddImage(imageDestination, cgImage, destinationProperties)
CGImageDestinationFinalize(imageDestination)
let image = UIImage(data: data as Data)
return image
}
}
在这里您可以修改 kCGImageSourceThumbnailMaxPixelSize 属性来调整图像大小。
信用:我跟着它