在 macOS 上显示 RAW 图像并应用滤镜的最佳方式是什么?

问题描述 投票:0回答:1

我正在为 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 中的错误。

image core-graphics metalkit
1个回答
0
投票

好吧 - 我终于弄清楚了,它很复杂但很简单。它很复杂,因为有太多的选项可供选择,还有太多过时的示例应用程序可供查看。无论如何,我认为我已经解决了大多数(如果不是全部)与使用金属支持的 CALayers 和应用 CIFilter 调整时渲染图像实时更新相关的问题。这个难题有很多部分,如果有人寻求帮助,我们很乐意分享。

一些关键提示:

  1. 我正在使用 CAMetalLayer 和 NSView
  2. 我重写了CAMetalLayer.display(layer:)方法,并在用户滑动调整滑块时调用layer.setNeedsDisplay()。
  3. 我将所有 CIFilter 链接在一起,包括使用 CIFilter(imageUrl:) 创建的 RAW 滤镜
  4. 最重要的是,我使用 RAW 滤镜scaleFactor 参数来调整图像大小 - 使用任何其他方法调整图像大小以适应视图大小时遇到了主要性能问题
  5. 如果图像直接放大,不要指望高性能 - 50% 似乎是尼康 D850 拍摄的 45 兆像素 RAW 图像的极限。

结果的短视频在这里 https://youtu.be/5wp0CIWAoIM

© www.soinside.com 2019 - 2024. All rights reserved.