【问题标题】:Create CGImage from Data multiple times results with previous image override使用先前的图像覆盖多次从数据创建 CGImage 结果
【发布时间】:2020-11-10 13:44:24
【问题描述】:

在生成CGImage 时,可以在使用JPEG 编码数据、PNG 编码数据或仅数据的初始化程序之间进行选择。我正在从包含 16 位灰度值的 Data 对象生成图像。 初始化程序需要一个CGDataProvider,它可以是顺序访问或直接访问数据提供程序。 在顺序访问下,我们只有一个初始化器:

  • 创建顺序访问数据提供程序

在 Direct-Access 下,我们有多个初始化器,但让我们关注一个子集:

  • 创建直接访问数据提供者
  • 创建使用程序提供的数据的直接访问数据提供程序
  • 创建从 CFData 对象读取的数据提供程序

我们可以肯定地注意到,直接访问列表中的最后一项在其定义中缺少“直接访问”术语。

第一个问题: 我理解顺序和直接访问内存的概念,但是考虑到 Swift 的行为,有人能给我一个更准确的定义吗?

让我们继续。 我的UIViewController 子类中有两个不同的Data 对象。 我正在从主调度队列调用我在助手类中的静态函数。 这个辅助函数获取Data,这是我创建CGImage 并将其返回给视图控制器的地方。 视图控制器将每个图像保存在一个单独的属性变量中。

这就是事情变得奇怪的地方:

使用“创建从 CFData 对象读取的数据提供程序” - 有效!

但我不想在 iOS 项目中使用 CoreFoundation 并创建一个 CFData 对象(这可能会将缓冲区复制到一个新对象中)

使用“创建一个使用您的程序提供的数据的直接访问数据提供程序” - 有效!

我正在使用withUnsafeBytes 访问原始缓冲区,它在闭包内为我提供了UnsafeRawBufferPointer

但是,如果我使用 withUnsafeMutableBytes 更改对 Data 的访问 - 返回到视图控制器的第二个图像会覆盖第一个图像!

我尝试使用 XCode 对其进行调试,并且每个图像实际上都是在辅助函数内部适当生成的,但是当第二个图像返回到视图控制器时,第一个图像发生了变化。

第二个问题: 什么会造成这种奇怪的行为?

这个过程有很多参与者,我想我已尽我所能尝试解决它。 任何反馈将不胜感激。

【问题讨论】:

    标签: core-graphics swift5 ios14 cgimage unsafe-pointers


    【解决方案1】:

    “直接访问”只是意味着所有字节始终可用,您可以按任意顺序访问它们。

    “顺序访问”意味着字节在流中,您只能在当前“头部”读取它们,向前跳过一些字节数,或者一直倒回到开头。你不能随便跳到任何你想跳的地方。例如,如果您从网络流式传输数据,您可能永远不会同时将所有数据存储在内存中。

    CFData 始终是直接访问的,因此无需在定义中调用它。这里与 Swift 无关。这些都是核心基础(即“C”)数据结构。 Swift 可以将 Data 桥接到 CFData,但这些接口早于 Swift。

    但我不想在 iOS 项目中使用 CoreFoundation 并创建一个 CFData 对象(这可能会将缓冲区复制到一个新对象中)

    数据无需复制即可桥接到 CFData。您只需添加as CFData。 Data 是 NSData 的基础覆盖,NSData 是 CFData 的免费桥梁。

    let data = Data(...)
    let source = CGImageSourceCreateWithData(data as CFData, nil)
    

    对于您关于特定行为的问题,我确定您有错误,但我们必须查看代码。如果我不得不猜测,我怀疑您依赖的是未承诺的对象生命周期。这是使用 Unsafe 类型时的常见错误。但是如果你已经有一个数据,我不会为自定义 CGImageSources 烦恼。如果您已经在内存中拥有所有数据,那么通常不需要进行大量工作。 (如果您仍然想这样做,请发布一些代码,我相信我们可以引导您完成它。这并不难,只是通常没有必要,而且在 Swift 中有点繁琐。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 2018-05-02
      • 1970-01-01
      • 2019-10-14
      • 2016-09-02
      • 2021-09-12
      • 1970-01-01
      相关资源
      最近更新 更多