如何压缩图像而不丢失元数据?

问题描述 投票:0回答:1

我有一个应用程序,可以从图库中选择照片,然后将其上传到服务器。

我对服务器端有 2 个要求:

  1. 将图像压缩至最大 1mb
  2. 图像应该有metada/exif数据

要从图库中选择图像,我正在使用新的 SwiftUI

.photosPicker

然后我使用

.loadTransferable
返回图像
Data

photo.loadTransferable(type: Data.self) { result in }

当我将这个

Data
加载到服务器时,EXIF/元数据就在那里。那太好了。但我需要压缩图像数据。 我找到了一种压缩图像数据的方法,如下所示:

UIImage(data: data)?.jpegData(compressionQuality: 1)

问题是,经过这次压缩,EXIF/元数据丢失了。

UIImage
切掉它。

问题:

如何压缩图像

Data
而不将其包装为
UIImage

或者有另一种方法来压缩图像数据并且不丢失EXIF/元数据吗?

ios swift uiimage
1个回答
0
投票

你是对的,将图像数据转换为 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
}

但是,有几个库(如 SDWebImageSwiftyJPEG)提供了在保留元数据的同时压缩图像的功能。这些库可能提供更简洁的解决方案,但会带来管理外部依赖项的开销

© www.soinside.com 2019 - 2024. All rights reserved.