Reputation: 31
Converting a UIImage to the WebP format is extremely slow. For a 2.5M HEIF photo with a compression ratio of 0.85, SDImageWebPCoder and libwebp take about 13.5 seconds.
SDImageWebPCoder
let webpCoder = SDImageWebPCoder.shared
var options: [SDImageCoderOption: Any] = [:]
options[SDImageCoderOption.encodeCompressionQuality] = 0.85
if let webpData = webpCoder.encodedData(with: image, format: .webP, options: options)
{
compressionImageData = webpData
}
libwebp
func convertToWebP(quality: CGFloat = 0.8) -> Data? {
// 先检查 UIImage 是否能获取到 CGImage
guard let cgImage = self.cgImage else { return nil }
let width = Int32(cgImage.width)
let height = Int32(cgImage.height)
// 创建一个 ARGB 格式的位图上下文
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bytesPerPixel = 4
let bytesPerRow = bytesPerPixel * Int(width)
let bitmapInfo = CGImageAlphaInfo.premultipliedFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
guard let context = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else { return nil }
// 将 CGImage 绘制到上下文中
context.draw(cgImage, in: CGRect(x: 0, y: 0, width: Int(width), height: Int(height)))
guard let pixelData = context.data else { return nil }
// 转换为 WebP 数据
var webpData: UnsafeMutablePointer<UInt8>?
let qualityFactor = Float(quality * 100)
let result = WebPEncodeRGBA(pixelData.assumingMemoryBound(to: UInt8.self), width, height, Int32(bytesPerRow), qualityFactor, &webpData)
if result > 0 {
let data = Data(bytes: webpData!, count: result)
WebPFree(UnsafeMutableRawPointer(webpData))
return data
}
return nil
}
Upvotes: 0
Views: 30