Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 将屏幕外CGLayer分屏到当前上下文时出现锯齿状路径_Performance_Core Graphics_Antialiasing_Cglayer_Blit - Fatal编程技术网

Performance 将屏幕外CGLayer分屏到当前上下文时出现锯齿状路径

Performance 将屏幕外CGLayer分屏到当前上下文时出现锯齿状路径,performance,core-graphics,antialiasing,cglayer,blit,Performance,Core Graphics,Antialiasing,Cglayer,Blit,在我当前的项目中,我需要绘制一个复杂的背景作为几个UITableView单元格的背景。由于在cell的drawRect:method中执行时,绘制此背景的代码非常长且CPU非常繁重,因此我决定只将其渲染一次到CGLayer,然后将其blit到cell以提高整体性能 我用于将背景绘制到CGLayer的代码: + (CGLayerRef)standardCellBackgroundLayer { static CGLayerRef standardCellBackgroundLayer;

在我当前的项目中,我需要绘制一个复杂的背景作为几个UITableView单元格的背景。由于在cell的drawRect:method中执行时,绘制此背景的代码非常长且CPU非常繁重,因此我决定只将其渲染一次到CGLayer,然后将其blit到cell以提高整体性能

我用于将背景绘制到CGLayer的代码:

+ (CGLayerRef)standardCellBackgroundLayer
{
    static CGLayerRef standardCellBackgroundLayer;

    if(standardCellBackgroundLayer == NULL)
    {
        CGContextRef viewContext = UIGraphicsGetCurrentContext();
        CGRect rect = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, PLACES_DEFAULT_CELL_HEIGHT);

        standardCellBackgroundLayer = CGLayerCreateWithContext(viewContext, rect.size, NULL);
        CGContextRef context = CGLayerGetContext(standardCellBackgroundLayer);

        // Setup the paths
        CGRect rectForShadowPadding = CGRectInset(rect, (PLACES_DEFAULT_CELL_SHADOW_SIZE / 2) + PLACES_DEFAULT_CELL_SIDE_PADDING, (PLACES_DEFAULT_CELL_SHADOW_SIZE / 2));
        CGMutablePathRef path = createPathForRoundedRect(rectForShadowPadding, LIST_ITEM_CORNER_RADIUS);

        // Save the graphics context state
        CGContextSaveGState(context);

        // Draw shadow
        CGContextSetShadowWithColor(context, CGSizeMake(0, 0), PLACES_DEFAULT_CELL_SHADOW_SIZE, [Skin shadowColor]);
        CGContextAddPath(context, path);
        CGContextSetFillColorWithColor(context, [Skin whiteColor]);
        CGContextFillPath(context);

        // Clip for gradient
        CGContextAddPath(context, path);
        CGContextClip(context);

        // Draw gradient on clipped path
        CGPoint startPoint = rectForShadowPadding.origin;
        CGPoint endPoint = CGPointMake(rectForShadowPadding.origin.x, CGRectGetMaxY(rectForShadowPadding));
        CGContextDrawLinearGradient(context, [Skin listGradient], startPoint, endPoint, 0);

        // Restore the graphics state and release everything
        CGContextRestoreGState(context);
        CGPathRelease(path);
    }

    return standardCellBackgroundLayer;
}
将图层blit到当前上下文的代码:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawLayerAtPoint(context, CGPointMake(0.0, 0.0), [Skin standardCellBackgroundLayer]);
}
这实际上做的很好,但我唯一的问题是圆角(检查静态方法)。当快速播放到屏幕上时,图像非常粗糙。当绘图代码位于其原始位置时,情况并非如此:在drawRect方法中

我怎样才能找回这个抗锯齿

出于某种原因,以下方法对消除混叠没有任何影响:

CGContextSetShouldAntialias(context, YES);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetAllowsAntialiasing(context, YES);

提前谢谢

我要回答我自己的问题,因为我早就想好了。 你应该建立一个视网膜感知上下文。这种锯齿只出现在视网膜装置上

要对抗此行为,您应该使用以下帮助器方法创建视网膜上下文:

// Begin a graphics context for retina or SD
void RetinaAwareUIGraphicsBeginImageContext(CGSize size) 
{
    static CGFloat scale = -1.0;

    if(scale < 0.0) 
    {   
        UIScreen *screen = [UIScreen mainScreen];

        if([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0)
        {    
            scale = [screen scale]; // Retina
        }
        else 
        {
            scale = 0.0; // SD
        }
    }

    if(scale > 0.0)
    {    
        UIGraphicsBeginImageContextWithOptions(size, NO, scale);   
    }
    else 
    {    
        UIGraphicsBeginImageContext(size);   
    }
}

只需使用
UIGraphicsBeginImageContextWithOptions
并将比例设置为
0.0
,即可简化此操作

很抱歉唤醒了一个旧帖子,但我偶然发现了它,所以其他人可能也会这么做。更多详细信息请参见
UIGraphicsBeginImageContextWithOptions

如果指定的值为
0.0
,则比例因子将设置为比例 设备主屏幕的系数


基本上,这意味着如果是视网膜显示,它将创建视网膜上下文,这样您可以指定
0.0
,并将坐标视为点。

回答得好!虽然我没有尝试过,但我会接受这个比我的答案更为最新的答案;)嘿@bitshiftcp,我试过你的答案,但它不起作用,我没有看到任何渲染的图形。你能帮我解决这个问题吗。
+ (CGLayerRef)standardCellBackgroundLayer
{
    static CGLayerRef standardCellBackgroundLayer;

    if(standardCellBackgroundLayer == NULL)
    {
        RetinaAwareUIGraphicsBeginImageContext(CGSizeMake(320.0, 480.0));
        CGRect rect = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, PLACES_DEFAULT_CELL_HEIGHT);

        ...