首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何缓存CGContextRef

如何缓存CGContextRef
EN

Stack Overflow用户
提问于 2012-08-08 07:43:16
回答 2查看 1.3K关注 0票数 4

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

我想到了CGBitmapContext,但这是否意味着每次缩放之后我都需要拆掉并设置一个新的上下文呢?问题是,在视网膜显示器上,线条绘制太慢(在iPad 2上是如此),尤其是在缩放时。are中有一个名为GoodNotes的应用程序,它很好地证明了这是可能的,并且可以顺利地完成,但我不明白他们是如何做到的。下面是我目前为止的代码(今天大部分时间的结果):

代码语言:javascript
复制
- (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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-08 11:48:40

瓶颈实际上是我使用CATiledLayer的方式。我想这是太多的更新与徒手信息。正如我在网上的文档和教程中看到的那样,我将其设置为详细级别,但最终我并不需要那么多。我只是连接了滚动视图委托,在完成缩放时清除了内容,并更改了图层的contentScale以匹配滚动视图。结果是美好的(它消失了,消失了,但这是无法帮助的)。

票数 1
EN

Stack Overflow用户

发布于 2012-08-08 08:34:25

首先,由于路径抚摸是最昂贵的操作,您不应该锁定它,因为这样可以防止您在不同的内核上同时绘制瓷砖。

其次,我认为您可以避免多次调用CGContextStrokePath,方法是在上下文中添加所有路径,并将它们完全抚摸。

代码语言:javascript
复制
[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,其中包含您的路径的平展位图图像,并重用该图像。这将无助于缩放(因为当细节级别发生变化时,您需要重新创建图像),但是在用户绘制非常长的路径时,这对于提高性能非常有用。

有一个非常有趣的世界自然发展委员会2012年会议视频关于这个主题:优化二维图形与动画性能

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11859901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档