石英绘图优化

Posted

技术标签:

【中文标题】石英绘图优化【英文标题】:Quartz drawing optimization 【发布时间】:2009-02-02 20:45:52 【问题描述】:

我有一个视图,它有一个背景图像和一个CGPath,当用户触摸屏幕时它会发生变化。使用CGContextDrawImage() 绘制图像然后在顶部绘制路径不够快,并且会阻碍触摸事件的性能。我想要的是有一个位图缓冲区,并且只绘制路径中的更改。因此,视图的drawRect() 将只是绘制缓冲区。我怀疑我需要使用CGContexts,但我不知道该怎么做。有其他优化方法吗?

编辑:

每次用户触摸屏幕时,我都会添加路径;所以“路径变化”是指向现有路径添加更多点。这就是为什么我认为我可以只缓冲图像并只绘制路径的“增量”而不是每次都绘制整个东西。目前我的绘图和事件逻辑是这样的:

-(void)drawRect
    //Draw the background image
    //Draw the whole path


-(void)touchesMoved
    //Add the touch point to the path
    [self setNeedsDisplay];

以这种方式绘制背景会使触摸事件采样的性能明显不如仅绘制路径。

【问题讨论】:

【参考方案1】:

如果背景图像没有改变(我不能确定是否改变),那么您应该将背景图像放在不同的 CoreAnimation 层中,该层包含路径在其顶部。这让 GPU 可以处理合成,而不是在您的 -drawRect 中完成所有工作。然后可以在可能的情况下缓存背景图像,您唯一需要更新的就是路径(您仍然可以避免在每一帧中完全重绘)。您还可以执行缩放或旋转路径等操作,而不必担心对背景图像的影响。

【讨论】:

【参考方案2】:

实际上,这几乎就是它的工作方式。传递给 drawRect 的上下文绘制到一个 CALayer 中,该 CALayer 会被缓冲,直到您执行需要视图重绘自身的操作。您提到“当用户触摸屏幕时”路径会更改 - 然后您是否在视图上设置 setNeedsDisplay?

如果您真的每次都有不同的路径,那么您将无法缓冲它。如果它是相同的,只要你没有调用 setNeedsDisplay,或者会影响它被调用的东西,那么支持你的视图的层应该被缓冲。我在图层中有很多这样的视图,都有很多花哨的 CG 东西(绘制和填充路径、剪切图像、着色等),而且性能很棒。

如果您有不同的路径(可能以视觉方式表示触摸) - 您可能想考虑使用替代视图 - 它们本身不会改变 - 或者可能在单个预渲染视图上使用视图动画?

如果这些都没有达到目标,请发布更多信息以帮助我们了解您要做什么。

【讨论】:

【参考方案3】:

我不是 100% 肯定它在 iPhone 上以这种方式工作,但在等效的 Mac OS X 类上,setNeedsDisplay: 是有效同步的,因此昂贵的绘图操作会破坏循环的性能。尝试将绘图代码放在每秒执行几次的计时器上,而不是在事件处理代码中显式调用它。

请参阅this CocoaBuilder thread 了解更多信息。

【讨论】:

【参考方案4】:

从您的编辑看来,您正在做某种绘图应用程序。

在这种情况下,我会尝试“未知”的建议(将背景图像放在与路径不同的图层/视图中)。事实上,无论如何我都会这样做。 你在使用 CGPath 吗?如果不是,那可能也值得这样做。

如果您仍然遇到问题,可能值得将当前的“编辑”(快速连续绘制的任何线条)分离到它们自己的路径中(在它们自己的图层/视图中),并在适当的空闲时间后将它们添加到主路径(使用计时器)。

【讨论】:

以上是关于石英绘图优化的主要内容,如果未能解决你的问题,请参考以下文章

石英 2D 绘图崩溃

scratch绘图程序优化 电子学会图形化编程scratch等级考试四级真题和答案解析2021-3

iOS Core Animation Advanced Techniques-图层性能优化

保存绘图时更改Matplotlib图窗口的分辨率?

MATLAB绘图—三维网格绘图(mesh)

如何通过 websocket 优化发送绘图?