我有一个应用程序,可以从图库中选择照片,然后将其上传到服务器。
我对服务器端有 2 个要求:
要从图库中选择图像,我正在使用新的 SwiftUI
.photosPicker
然后我使用
.loadTransferable
返回图像 Data
。
photo.loadTransferable(type: Data.self) { result in }
当我将这个
Data
加载到服务器时,EXIF/元数据就在那里。那太好了。但我需要压缩图像数据。
我找到了一种压缩图像数据的方法,如下所示:
UIImage(data: data)?.jpegData(compressionQuality: 1)
问题是,经过这次压缩,EXIF/元数据丢失了。
UIImage
切掉它。
问题:
如何压缩图像
Data
而不将其包装为UIImage
?
或者有另一种方法来压缩图像数据并且不丢失EXIF/元数据吗?
你是对的,将图像数据转换为 UIImage,然后用 jpegData 压缩它会删除 EXIF 数据。以下是实现压缩和保留 EXIF 数据的方法:
此方法使用 CGImageSource 和 CGImageDestination 创建图像的压缩版本,同时保持 EXIF 数据完整。
func compressImage(data: Data, targetSize: Int = 1024 * 1024) throws -> Data {
guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {
throw NSError(domain: "com.yourapp.error", code: 1, userInfo: ["message": "Failed to create image source"])
}
let options: CFDictionary = [
kCGImageDestinationLosslessDecodeForEditing: kCFBooleanTrue,
kCGImageDestinationAllowPartialDecoding: kCFBooleanTrue,
kCGImagePropertyMagicNumber: kCFDataRef(data),
]
let compressedData = NSMutableData()
guard let destination = CGImageDestinationCreateWithData(compressedData as CFMutableData, kUTTypeJPEG, 1, options) else {
throw NSError(domain: "com.yourapp.error", code: 1, userInfo: ["message": "Failed to create image destination"])
}
// Set compression quality (adjust as needed)
let quality = 0.8
let properties = [kCGImageDestinationJPEGQuality: quality]
CGImageDestinationAddImageFromSource(destination, source, 0, properties)
if !CGImageDestinationFinalize(destination) {
throw NSError(domain: "com.yourapp.error", code: 1, userInfo: ["message": "Failed to finalize image destination"])
}
return compressedData as Data
}
但是,有几个库(如 SDWebImage 或 SwiftyJPEG)提供了在保留元数据的同时压缩图像的功能。这些库可能提供更简洁的解决方案,但会带来管理外部依赖项的开销