2012-08-08 93 views
4

我不满意我以前的结果,我被要求创建一个徒手画图视图,放大时不会模糊。我能想象得到的唯一方法是使用CATiledLayer,否则在缩放时画线时太慢。目前,我已经设置好每次都会重新绘制每一行,但是我想知道是否可以在上下文中缓存以前行的结果(而不是,因为它们需要很好地缩放) 。如何缓存CGContextRef

我想过CGBitmapContext,但这是否意味着我需要拆除并在每次缩放后设置新的上下文?问题在于,在视网膜显示器上,线条绘制太慢(在iPad 2上它太平常了),特别是在缩放绘制时。在App Store中有一个名为GoodNotes的应用程序,它很好地证明了这是可能的,并且可以顺利进行,但我无法理解他们是如何做到的。这是到目前为止我的代码(当今大多数的结果):

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef c = UIGraphicsGetCurrentContext(); 

    CGContextSetLineWidth(c, mLineWidth); 
    CGContextSetAllowsAntialiasing(c, true); 
    CGContextSetShouldAntialias(c, true); 
    CGContextSetLineCap(c, kCGLineCapRound); 
    CGContextSetLineJoin(c, kCGLineJoinRound); 

    //Protect the local variables against the multithreaded nature of CATiledLayer 
    [mLock lock]; 
    NSArray *pathsCopy = [mStrokes copy]; 
    for(UIBezierPath *path in pathsCopy) //**Would like to cache these** 
    { 
     CGContextAddPath(c, path.CGPath); 
     CGContextStrokePath(c); 
    } 
    if(mCurPath) 
    { 
     CGContextAddPath(c, mCurPath.CGPath); 
     CGContextStrokePath(c); 
    } 

    CGRect pathBounds = mCurPath.bounds; 
    if(pathBounds.size.width > 32 || pathBounds.size.height > 32) 
    { 
     [mStrokes addObject:mCurPath]; 
     mCurPath = [[UIBezierPath alloc] init]; 
    } 
    [mLock unlock]; 
} 

剖析展示了最热门的功能目前是GCSFillDRAM8by1

回答

1

瓶颈实际上是我使用CATiledLayer的方式。我想用Freehand信息更新太多了。我在网上的文档和教程中看到了详细程度的设置,但最终我并不需要那么多。我刚刚连接了scrollview委托,在完成缩放后清除了内容,并将层的contentScale更改为与滚动视图匹配。结果是美丽的(它消失并消失,但不能帮助)。

1

首先,作为路径行程是最昂贵的操作,你不应该锁定它,因为这会阻止您在不同内核上同时绘制切片。

其次,我想你可以避免多次呼叫CGContextStrokePath,通过添加上下文中的所有路径并完全抚摸它们。

[mLock lock]; 
for (UIBezierPath *path in mStrokes) { 
    CGContextAddPath(c, path.CGPath); 
} 
if (mCurPath) { 
    CGContextAddPath(c, mCurPath.CGPath); 
} 
CGRect pathBounds = mCurPath.bounds; 
if (pathBounds.size.width > 32 || pathBounds.size.height > 32) 
{ 
    [mStrokes addObject:mCurPath]; 
    mCurPath = [[UIBezierPath alloc] init]; 
} 
[mLock unlock]; 
CGContextStrokePath(c); 

CGContextRef只是一个绘图操作发生的画布。你不能缓存它,但你可以创建一个CGImageRef与你的路径的平面位图图像,并重用该图像。这对缩放没有帮助(因为在细节层次发生变化时需要重新创建图像),但在用户绘制真正漫长的路径时可以提高性能。

关于该主题,有一个非常有趣的WWDC 2012会话视频:Optimizing 2D Graphics and Animation Performance

+0

我已经看到过这个会话,但不幸的是它没有考虑缩放。其实我相信我已经找到了我的瓶颈(根本不是drawRect的一部分)。我会在多次测试后发布更多信息。 – borrrden 2012-08-08 09:02:50

+0

我发现了瓶颈,但您的建议也很有帮助,并且准确无误,所以我给了您一个+1 – borrrden 2012-08-08 11:46:52