一种简单的提取照片iCC的方式基于Swift
1. 痛点:当前自动化提取程度不高
在日常处理图像时,为了做色彩管理的分析或更精确的图像计算,我们经常需要获取照片自带的 ICC 配置文件(ICC Profile)。但是,想要优雅地提取这些底层的 ICC 数据却并不轻松。虽然业界有如 ExifTool 这样异常强大的跨平台综合体工具,但它们本质上仍然高度依赖命令行调用和进程执行。这使得在个人工作流工具或原生 App 中集成它时,自动化和无缝联动的程度都不高,同时还引入了外部依赖这层“包袱”。
2. 新的方案:Swift的Apple官方SDK的原生的便捷提取方案 colorSpace.copyICCData()
colorSpace.copyICCData()是苹果官方SDK支持的简单提取方案,可以在Mac或者开发中简单调用和使用,对于苹果流的用户,这是简单的方案。
代码核心逻辑
稍微分析一下思路,如果我们要提取数据并落地成文件,核心逻辑可以从 colorSpace.copyICCData() 开始:
- 我们的终极目标是调用
copyICCData()收割数据,而这个方法属于CGColorSpace对象。 - 那如何拿到
CGColorSpace呢?很简单,我们需要一个图形对象CGImage,读取它的.colorSpace属性。 - 进一步往上游回溯,
CGImage是通过CGImageSource(也就是我们的硬盘图片资源) 创建出来的。
理清了这个顺理成章的依赖链条后,提取逻辑用 Swift 如下:
1 | import Foundation |
⚠️ 一个不能忽略的细节:数据格式转换
在这套流程中,有一个极为关键的数据格式转换动作需要专门强调:“把 CFData 转为 Data”。
由于 colorSpace.copyICCData() 是一个来源于底层的 C API,它提取出 ICC 信息后,抛给我们的返回值是 Core Foundation 层级的 CFData?。但作为现代 Swift 开发者,如果你想要借助于 URL 直接优雅地写数据流落盘,你必须用到原生的 Data 类型。
好在 Swift 为我们提供了 Foundation 与 Core Foundation 免费的桥接机制 (Toll-Free Bridging),我们只需要极其简单的一步显式转换:
1 | let data = cfICCData as Data |
一旦完成这步强转,这团内存就化身成为了强大的 Swift原生 Data,无论是校验字节长度 (data.count) 还是调用 try data.write(to: outputURL) 一键归档,一切都那么自然顺滑。
3. 总结
相比较于去满世界捞第三方 CLI 脚本库并强行接入,Swift 原生提供的基于 colorSpace.copyICCData() 的这套 API 工作流更加编辑,且可以自由Conding搭配。无需额外的三方依赖库,无需进程管理,它通过几行代码直接打通了从图片文件载入到提取深层 Profile 数据,再到落盘写回磁盘的完整闭环。是各位图像相关工作者在 Apple 生态下首选的原生自动化方案。