我正在为 macOS 创建一个简单的照片目录应用程序,看看最新的 API 是否可以显着提高加载包含大量图像的目录的性能。
到目前为止,它看起来很有前途,使用
QLThumbnailGenerator
和 CGImageSourceCreateWithURL
加载大约 600 个 45MB RAW 图像缩略图速度非常快,几乎可以立即显示缩略图图像和图像元数据。
在 NSCollectionViewItem 视图中使用 CALayer 在 NSCollectionView 中显示这些图像似乎也非常快,并且滚动非常流畅。
我确实发现,如果我连续循环调用 api,
QLThumbnailGenerator
似乎在几百张图像后开始失败,并开始返回错误代码 108 - 我通过在缩略图生成器 api 调用后立即调用 CGImageSourceCopyPropertiesAtIndex
来解决这个问题 - 所以如果 API 调用得太快且时间太长,可能存在计时问题或文件句柄不足或其他问题。
但是,我仍然无法将全尺寸图像渲染到显示器上 - 这里我使用 NSScrollView 和图层支持的 NSView documentView。一切都超级快,直到以下电话:
view.layer.contents = cgImage
此时整个主线程将挂起,直到图像加载 - 这可能需要几秒钟。
一旦加载就很好,通过更改 documentView 帧大小来放大和缩小非常快 - 滚动全尺寸图像也非常流畅,没有任何典型的打嗝。
有没有办法加载这些图像而不导致 UI 冻结?
我看过最近的 WWDC2020 会议,他们演示了类似的大量图像滚动,但除了 CATiledLayer 之外,我还没有找到任何关于加载大图像的有用信息 - 但目前还不清楚这是否是正确的答案这个问题。
旧的 Apple 示例 RawExpose 似乎是一个选项,但大部分代码已被弃用,似乎必须使用 MetalKit 而不是 GLKit - 不幸的是,我找不到将 MetaKit 与 Core Image 结合使用的示例。
仅供参考 - 我尝试使用一些新的 SwiftUI CollectionView 和 List,但它们似乎比 AppKit 慢得多,而且我发现一些集合视图项目永远不会渲染 - 当然这些可能只是 macOS 11 beta 中的错误。
好吧 - 我终于弄清楚了,它很复杂但很简单。它很复杂,因为有太多的选项可供选择,还有太多过时的示例应用程序可供查看。无论如何,我认为我已经解决了大多数(如果不是全部)与使用金属支持的 CALayers 和应用 CIFilter 调整时渲染图像实时更新相关的问题。这个难题有很多部分,如果有人寻求帮助,我们很乐意分享。
一些关键提示:
结果的短视频在这里 https://youtu.be/5wp0CIWAoIM