如何通过CGImageSource直接提取图片内嵌缩略图
直接从CGImageSource获取内嵌缩略图的可行方案
当然可以!既然你已经持有CGImageSource引用,直接读取内嵌缩略图绝对是比生成新缩略图或者调用NSWorkspace.shared.icon(forFile:)更高效的选择——毕竟绕开了重复的文件IO和计算开销。下面给你具体的实现思路和代码示例:
两种常见的内嵌缩略图存储方式
图片的内嵌缩略图通常有两种存储形式,我们可以分别处理,或者用更省心的统一方法:
1. 缩略图作为独立的图像源
有些格式(比如JPEG)会把缩略图作为CGImageSource中的第二个图像(索引为1)。你可以先检查图像源的图像数量:
let imageSource: CGImageSource = ... // 你的CGImageSource实例 if CGImageSourceGetCount(imageSource) > 1 { if let thumbnailCGImage = CGImageSourceCreateImageAtIndex(imageSource, 1, nil) { let thumbnailImage = NSImage(cgImage: thumbnailCGImage, size: NSSize( width: CGImageGetWidth(thumbnailCGImage), height: CGImageGetHeight(thumbnailCGImage) )) // 拿到缩略图了,直接用就行 } }
2. 缩略图存储在图像属性字典中
另一种常见形式是把缩略图数据嵌入主图像的属性字典里,我们可以从属性中提取:
if let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [CFString: Any], let thumbnailDict = properties[kCGImagePropertyThumbnailDictionary] as? [CFString: Any], let thumbnailData = thumbnailDict[kCGImagePropertyThumbnailData] as? Data { if let thumbnailSource = CGImageSourceCreateWithData(thumbnailData as CFData, nil), let thumbnailCGImage = CGImageSourceCreateImageAtIndex(thumbnailSource, 0, nil) { let thumbnailImage = NSImage(cgImage: thumbnailCGImage, size: NSSize( width: CGImageGetWidth(thumbnailCGImage), height: CGImageGetHeight(thumbnailCGImage) )) // 处理缩略图 } }
更省心的统一方案:用CGImageSourceCreateThumbnailAtIndex指定选项
其实苹果已经提供了更智能的方法,让CGImageSourceCreateThumbnailAtIndex优先使用内嵌缩略图,而不是生成新的。只需要设置对应的选项即可,它会自动处理上面两种存储形式:
let thumbnailOptions: [CFString: Any] = [ kCGImageSourceCreateThumbnailWithTransform: true, // 自动修正缩略图的方向 kCGImageSourceCreateThumbnailFromImageAlways: false, // 只使用内嵌缩略图,不生成新的 kCGImageSourceThumbnailMaxPixelSize: 256 // 按需设置缩略图的最大尺寸 ] if let thumbnailCGImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, thumbnailOptions as CFDictionary) { let thumbnailImage = NSImage(cgImage: thumbnailCGImage, size: NSSize( width: CGImageGetWidth(thumbnailCGImage), height: CGImageGetHeight(thumbnailCGImage) )) // 使用缩略图 } else { // 没有找到内嵌缩略图,再考虑生成或者调用NSWorkspace的方法 }
关于NSWorkspace方法的性能对比
NSWorkspace.shared.icon(forFile:)的开销确实更大:它需要重新读取文件的元数据,甚至可能在没有内嵌缩略图时实时生成,而你已经持有CGImageSource,意味着文件数据已经加载到内存中了,直接从这里读取缩略图的IO开销几乎为零,效率高很多。
内容的提问来源于stack exchange,提问作者bauerMusic
相关产品推荐
相关产品推荐

