Swift跨平台压缩图片Data:无需UIImage的实现方案咨询
SwiftUI跨平台图片压缩方案(不依赖UIKit)
一、基于SwiftUI原生ImageRenderer的跨平台方案(iOS 16+/macOS 13+)
如果你的应用目标版本满足iOS 16、macOS 13及以上,完全可以用SwiftUI自带的ImageRenderer实现跨平台图片压缩,无需依赖UIKit或AppKit的私有API。
核心思路:将原始Data转为SwiftUI的Image,再通过ImageRenderer将图片渲染为指定尺寸、质量的压缩数据。
示例代码:
import SwiftUI func compressedImageData(from rawData: Data, targetSize: CGSize, quality: CGFloat = 0.8) -> Data? { #if os(iOS) guard let uiImage = UIImage(data: rawData) else { return nil } let swiftUIImage = Image(uiImage: uiImage) #elseif os(macOS) guard let nsImage = NSImage(data: rawData) else { return nil } let swiftUIImage = Image(nsImage: nsImage) #endif let renderer = ImageRenderer(content: swiftUIImage) #if os(iOS) renderer.scale = UIScreen.main.scale #elseif os(macOS) renderer.scale = NSScreen.main?.backingScaleFactor ?? 1.0 #endif renderer.size = targetSize return renderer.jpegData(compressionQuality: quality) }
二、兼容旧版本的平台差异化封装
如果需要支持iOS 15及以下、macOS 12及以下,ImageRenderer不可用,这时需要分别用UIKit(iOS)和AppKit(macOS)的图片处理能力,但可以通过条件编译封装成统一的工具函数,上层代码无需关心平台差异。
示例代码:
import SwiftUI func compressedImageData(from rawData: Data, targetSize: CGSize, quality: CGFloat = 0.8) -> Data? { #if os(iOS) guard let uiImage = UIImage(data: rawData), let resizedImage = uiImage.resized(to: targetSize) else { return nil } return resizedImage.jpegData(compressionQuality: quality) #elseif os(macOS) guard let nsImage = NSImage(data: rawData), let resizedImage = nsImage.resized(to: targetSize) else { return nil } return resizedImage.tiffRepresentation #endif } // iOS平台扩展UIImage #if os(iOS) extension UIImage { func resized(to size: CGSize) -> UIImage? { let renderer = UIGraphicsImageRenderer(size: size) return renderer.image { _ in draw(in: CGRect(origin: .zero, size: size)) } } } #endif // macOS平台扩展NSImage #if os(macOS) extension NSImage { func resized(to size: CGSize) -> NSImage? { let newImage = NSImage(size: size) newImage.lockFocus() let rect = CGRect(origin: .zero, size: size) draw(in: rect, from: .zero, operation: .copy, fraction: 1.0) newImage.unlockFocus() return newImage } } #endif
总结
- 若目标版本足够新(iOS 16+/macOS 13+),优先用
ImageRenderer实现纯SwiftUI跨平台压缩,代码简洁统一; - 若需兼容旧版本,通过条件编译封装平台特定的图片处理逻辑,上层调用保持一致,避免直接暴露UIKit/AppKit给业务代码。
内容的提问来源于stack exchange,提问作者user19642312
相关产品推荐
相关产品推荐

