You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PhotosPickerItem上传图片并压缩后保存至Core Data?

可以实现,以下是具体方案

当然能在保存到Core Data前压缩图片大小,核心逻辑是拿到PhotosPickerItem的图片数据后,先转成UIImage,通过尺寸调整+质量压缩双重处理减小文件体积,最后用压缩后的二进制数据存入Core Data。

结合你现有的代码,只需要修改onChange里的处理逻辑:

Section {
    VStack {
        PhotosPicker("Select an Image", selection: $photoItem, matching: .any(of: [.images, .not(.livePhotos)]))
        
        if let image {
            Image(uiImage: (UIImage(data: image)?.resizeWithWidth(width: 400)! ?? UIImage(systemName: "photo"))!)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .scaledToFit()
                .frame(width: 300, height: 300)
        }
    }
    .onChange(of: photoItem) { _ in
        Task {
            guard let data = try? await photoItem?.loadTransferable(type: Data.self),
                  let originalImage = UIImage(data: data),
                  // 先通过你已有的方法调整图片尺寸
                  let resizedImage = originalImage.resizeWithWidth(width: 400),
                  // 再进行质量压缩,compressionQuality取值0-1,值越小体积越小、画质越低
                  let compressedData = resizedImage.jpegData(compressionQuality: 0.7) else {
                print("Failed to process image")
                return
            }
            image = compressedData
            // 后续将image存入Core Data即可
        }
    }
}

关键细节说明:

  • 尺寸优先:你已经实现的resizeWithWidth是减小体积最直接的方式,大幅降低像素量后,再做质量压缩效果更明显。
  • 格式适配:jpegData(compressionQuality:)适合非透明图片,压缩比高;如果是带透明通道的PNG图,该方法会返回nil,此时可以改用resizedImage.pngData(),但PNG是无损压缩,体积会比JPEG大。
  • 容错处理:用guard let集中处理各个步骤的失败情况,避免强制解包引发崩溃。

内容的提问来源于stack exchange,提问作者Alexander Johansson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 00:45:46