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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:42:51