Image I/O 是 Apple 提供的一个高性能、底层图像处理框架,包含在 Core Graphics/Core Services 中,核心类为 CGImageSource(读取图像)和 CGImageDestination(写入图像)。
可以把它理解为一种对图像进行读写、转换、压缩、编码的标准接口,适用于 JPG、PNG、HEIC、TIFF 等格式,比 NSBitmapImageRep 更底层、更灵活。
实现代码
import Cocoa
import ImageIO
import UniformTypeIdentifiers
func compressImageWithImageIO(_ nsImage: NSImage, type: CFString = UTType.jpeg.identifier as CFString, quality: CGFloat = 0.5) -> Data? {
// 将 NSImage 转换为 CGImage
guard let tiffData = nsImage.tiffRepresentation,
let source = CGImageSourceCreateWithData(tiffData as CFData, nil),
let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil) else {
return nil
}
// 创建用于接收压缩后数据的容器
let outputData = NSMutableData()
guard let destination = CGImageDestinationCreateWithData(outputData, type, 1, nil) else {
return nil
}
// 压缩选项(0.0 = 最小质量,1.0 = 最佳质量)
let options: [CFString: Any] = [
kCGImageDestinationLossyCompressionQuality: quality
]
// 添加图像到目标
CGImageDestinationAddImage(destination, cgImage, options as CFDictionary)
// 完成写入
if CGImageDestinationFinalize(destination) {
return outputData as Data
} else {
return nil
}
}
使用示例:
if let nsImage = NSImage(contentsOf: URL(fileURLWithPath: "/Users/xxx/Pictures/input.png")) {
if let compressedData = compressImageWithImageIO(nsImage, type: UTType.jpeg.identifier as CFString, quality: 0.3) {
try? compressedData.write(to: URL(fileURLWithPath: "/Users/xxx/Pictures/output.jpg"))
}
}
支持格式
1、JPEG:传入值kUTTypeJPEG / UTType.jpeg.identifier as CFString。
2、PNG:传入值:kUTTypePNG / UTType.png.identifier as CFString,压缩支持很差。
3、HEIC:UTType.heic.identifier as CFString,支持版本macOS 10.13+。
4、TIFF:kUTTypeTIFF。
5、GIF:kUTTypeGIF,不建议用于GIF压缩。
总结
CGImageDestination可以实现压缩图片的功能。
CGImageDestination 支持的是一次性输出,不能多次更新或追加图片内容(除非做多帧图)。
PNG 没有有损压缩,所以 .compressionQuality 对 PNG 没有效果,建议转 JPG或使用第三方库压缩PNG。
想支持 WebP 的话,macOS 原生不支持,需要用第三方库(如 libwebp 或 SDWebImageWebPCoder)。
经过实际测试发现:CGImageDestination可以对jpg、jpeg、exr和heic这四种格式的图片,可以实现很好的压缩。
1、HEIC格式,可以压缩94%。
2、EXR格式,可以压缩94%。
3、JPG和JPEG格式,最低可以压缩 65% 。
4、PNG格式,最低可以压缩35%。
5、GIF格式,只能压缩成单图。
6、WEBP格式和TIFF格式,输出原图。

总的来说,比NSBitmapImageRep新增了exr和heic的压缩支持,并且不会出现反向压缩的场景。
相关文章
macOS位图类NSBitmapImageRep:https://fangjunyu.com/2025/07/10/macos%e4%bd%8d%e5%9b%be%e7%b1%bbnsbitmapimagerep/