如何通过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
相关产品推荐
相关产品推荐

