【问题标题】:IKImageView choppy?IKImageView 断断续续?
【发布时间】:2010-07-30 14:31:15
【问题描述】:

我有一个 IKImageView,我将 CGImages(我用 NSImages 制作)放到它上面。然而,一个正常的 200DPI 8.5/11 页面需要大约 3 秒才能出现,一次出现在一边大约 2 英寸(屏幕)的矩形中。这真的很烦人。有没有办法解决这个问题?

或者,有没有办法双重缓冲视图?有2个IKImageViews并画成一个,然后显示?

预计到达时间: 将我的滚动视图(里面有 ikimageviews)加倍,然后绘制它们,然后取消隐藏它们,似乎没有帮助......或者,也许它有一点帮助,但没有多大帮助

我在仪器上摸索了一下,发现在 memcopy 中似乎做了很多工作:

  22 commpage [libSystem.B.dylib] 78.0  __memcpy
  21 ImageIO 37.0  CGImageReadGetBytesAtOffset
  20 ImageIO 37.0  CGImageReadSessionGetBytes
  19 ImageIO 37.0  myTIFFReadProc
  18 libTIFF.dylib 37.0  TIFFReadRawStrip1
  17 libTIFF.dylib 37.0  TIFFFillStrip
  16 libTIFF.dylib 37.0  _cg_TIFFReadEncodedStrip
  15 ImageIO 37.0  copyImageBlockSetTIFF
  14 ImageIO 37.0  ImageProviderCopyImageBlockSetCallback
  13 CoreGraphics 37.0  CGImageProviderCopyImageBlockSet
  12 CoreGraphics 37.0  img_blocks_create
  11 CoreGraphics 37.0  img_blocks_extent
  10 CoreGraphics 37.0  img_interpolate_extent
   9 CoreGraphics 37.0  img_data_lock
   8 CoreGraphics 37.0  CGSImageDataLock
   7 libRIP.A.dylib 37.0  ripc_AcquireImage
   6 libRIP.A.dylib 37.0  ripc_DrawImage
   5 CoreGraphics 37.0  CGContextDrawImage
   4 ImageKit 37.0  -[IKImageLayer drawInContext:]
   3 QuartzCore 37.0  tiled_layer_render(_CAImageProvider*, unsigned int, unsigned int, unsigned int, unsigned int, void*)
   2 QuartzCore 37.0  CAImageProviderThread(void*)
   1 libSystem.B.dylib 37.0  _pthread_wqthread
   0 libSystem.B.dylib 37.0  start_wqthread

我不确定这告诉我什么...

编辑:为了记录,问题是 NOT 数据大小。我有一个旧版本的程序,它使用不推荐使用的 quickdraw 方法调用。当我将图像放大到 300% 时,一个屏幕像素 = 一个图像像素,所以它需要使用整个图像,它仍然一页接一页地压缩。

我被最初写这篇文章的人嘲笑了,因为他的版本在他古老的 10.3 G5 上比在我最新的 Intel 机器上运行得更快。速度至少快 10 倍。

【问题讨论】:

  • 你是如何创建 NSImage 和 CGI​​mageRef 的?
  • 最初,我使用扫描仪的位图数据制作图像。目前,我似乎将其放入 CGImageProvider 中,从中获取 CGImage,将该图像放入 NSData 的 CGImageDestination 中,然后使用该数据制作 NSImage。现在我看,它看起来很傻...... hrm。
  • 您的问题解决了吗?我有同样的问题

标签: objective-c cocoa nsimage ikimageview


【解决方案1】:

200DPI 8.5/11 页

假设这些是 RGB 颜色,则每张图像有 11.22 兆字节的像素。您的应用程序使用大量内存,并且绘制 3.74 兆像素(无论色彩空间如何)会很慢。

侧面 2 英寸(屏幕)

利用它。使用 72 dpi 常数和the window's user-space scale factor 计算 2 英寸屏幕像素的数量,然后将您的页面光栅化为该尺寸。目前,这些矩形边长为 144 个点,而 144×144 的图像在内存和绘制中非常有效。

如果您有缩放设置,您会希望在这些图像发生更改时使您的缓存无效,并且不早于您的视图被告知要绘制时重新计算每个图像。

【讨论】:

  • 嗯,1 目前是黑白的,但更重要的是,在过去,在我使用 IKImageView 之前,它需要大约 1/20 的时间。我没有夸大其词。在绘制屏幕需要 0.1 秒之前,不太可能。现在是 2 秒。那是很长的时间......扫描页面只需要1/2秒......
  • 你应该在 Instruments 中分析你的应用,看看它在这段时间内花费了什么。
  • 我应该使用哪种仪器?仪器似乎是一个巨大的工具,我从来没有完全弄清楚......
  • 哦,那你有没有发现一些令人愉快的发现! :-) 花时间学习这个工具 - 你不会后悔的。
  • 好吧,正如我在上面添加的那样,似乎时间都花在了 memcopy 上,但这对我并没有太大帮助......