【问题标题】:Drawing chart with lots of points efficiently on iOS在 iOS 上高效绘制多点图表
【发布时间】:2016-01-19 21:35:45
【问题描述】:

我正在寻找一种在 iOS 上有效地绘制包含大量点(最多 10 000 个)的折线图的方法。图表获取实时数据,需要每秒更新多次。我正在尝试找出一种方法来有效地绘制图形,这样它就不会在绘制时最大化 CPU 并阻塞主线程。

我目前正在后台线程中为折线图创建UIBezierPath,添加所有点并将其绘制在 CALayer(启用了异步绘图)中。它不是很快,会耗尽 CPU 并且绘图速度很慢,UI 变得迟钝。我正在绘制实时数据,理论上我可以每次重复使用相同的UIBezierPath 并添加新点,但是一段时间后会丢弃旧值,这意味着必须从贝塞尔路径,这是不可能的。

我还没有找到任何关于在 iOS 上高效绘制大型数据集的方法,但我希望有办法使用 GPU 来提高性能。

【问题讨论】:

  • 你必须画出所有的 10k 点吗?即使在 iPad 屏幕上,这似乎也太过分了……(比水平像素多点)。您是否考虑过将数据平均到一个较小的集合中?
  • @originaluser2 我完全同意。我正在做一些客户工作,但还没能说服他们放弃绘制这么多点的想法。
  • 好吧,如果你能说服他们,平均是你最好的选择!我怀疑您是否能够充分利用 GPU 而无需完全使用 Metal/Open GL。我很确定UIBezierPath 主要使用核心图形,并且全部在 CPU 上运行。
  • SciChart iOS 轻松支持超过 10k 点(测试高达 1M 点)。 2.3 版将支持 Metal 以及模拟器的 OpenGLES scichart.com/ios-chart-performance-comparison

标签: ios graph plot drawing core-graphics


【解决方案1】:

几年前(iPhone 4 天)我遇到过这样的情况。

我使用了CGMutablePathRef,我使用CGPathMoveToPoint 为第一点添加了点,CGPathAddLineToPoint 用于后续点。

为了获得可接受的性能,我将数据点存储在 C 数组中(不是NSArray)。此外,当绘制一个点时,如果它的显示坐标与上一个绘制的点相同,我只是跳过了对CGPathAddLineToPoint 的调用。 (当数据点多于像素时,通常会出现这种情况)。

我不记得确切的绘制时间,但速度非常快。

【讨论】:

  • 如果您无法对数据集进行平均,那么这绝对是下一个最佳选择。 (没有全金属)
【解决方案2】:

您可以设置CGBitmapContext,然后“手动”绘制点,而不是使用UIBezierPath 绘制点,例如

color = (0xFF << 24) | (blue << 16) | (green << 8) | (red); // AABBGGRR
for (loop = 0; loop < count; loop++)
{
    index = indices[loop];
    self.pixels[index] = color;
}

其中 self.pixels 是用于创建 CGBitmapContext 的缓冲区。然后,在drawRect中:

CGContextRef c = UIGraphicsGetCurrentContext();

CGImageRef image = CGBitmapContextCreateImage(self.imageContext);
CGContextDrawImage(c, self.bounds, image);
CGImageRelease(image);

我认为您会发现这比使用 CGPath 或 UIBezierPath 快得多(而且更小)。

【讨论】:

    【解决方案3】:

    我终于找到了一个用 OpenGL 绘制图形的实现:https://github.com/syedhali/EZAudio/blob/master/EZAudio/EZAudioPlotGL.m

    其实很简单,而且性能提升很大。

    对于配备 A7 芯片(或更新版本)的设备,用金属绘制图形可能会更快,这也应该很容易。有一些关于如何做到这一点的指南:https://www.raywenderlich.com/77488/ios-8-metal-tutorial-swift-getting-started

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多