CALayer 中的抗锯齿绘图

Posted

技术标签:

【中文标题】CALayer 中的抗锯齿绘图【英文标题】:Antialiased drawing in a CALayer 【发布时间】:2011-05-20 19:27:57 【问题描述】:

您好!我正在尝试在位于可缩放 UISCrollView 中的 CALayer 中绘制一系列圆圈。这是放大捏合的图层。如果我使用 CAShapeLayer 绘制圆圈,那么它们会很好地缩放:

CAShapeLayer plotLayer = [CAShapeLayer layer];
plotLayer.bounds = self.bounds;
plotLayer.anchorPoint = CGPointZero;
plotLayer.position = CGPointZero;

CGMutablePathRef path = CGPathCreateMutable();
for (id one in many) 
    CGRect ellipseRect = [one circleRect];
    CGPathAddEllipseInRect(path, NULL, ellipseRect);

plotLayer.path = path
CFRelease(path);
[self.layer addSublayer:plotLayer];
[plotLayer setNeedsDisplay];

但是,当我尝试在我的 drawLayer:inContext: 方法中使用 vanilla 核心图形绘制它们时,圆圈变得非常锯齿(彻头彻尾的亲锯齿!)没有任何抗锯齿 jiggery-pokery 似乎有帮助:

-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context

    CGContextSetAllowsAntialiasing(context, true);
    CGContextSetShouldAntialias(context, true);
    CGContextClip(context);

    for (id one in many) 
        CGRect ellipseRect = [one circleRect];
        CGContextStrokeEllipseInRect(context, ellipseRect);
    

我试图弄清楚 CAShapeLayer 正在做什么来获得如此好的抗锯齿效果,以便(除了我自己的启发之外)我可以在我的绘图中充分利用核心图形,而不仅仅是我可以获得的笔触/填充与 CAShapeLayer。我只是错过了某个地方的转换吗?

非常感谢!

【问题讨论】:

【参考方案1】:

简答:contentsScale

更长的答案:(从Vector like drawing for zoomable UIScrollView的pe8ter几乎逐字记录):

您可以通过在缩放后在相关图层上设置 contentScale 属性来获得更好的渲染效果:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView
                       withView:(UIView *)view
                        atScale:(float)scale

    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithBool:YES] 
                     forKey:kCATransactionDisableActions];
    uglyBlurryTextLayer.contentsScale = scale;
    [CATransaction commit];

在So a CALayer does not contain a content bitmap of a view? 上,Brad Larson 对实际绘图何时发生(剧透,尽管应用了多少变换,它通常只发生一次)进行了(通常非常出色)的描述。基于此,我只能假设设置 contentsScale 会导致图层再次渲染。

【讨论】:

【参考方案2】:

我还没有尝试过,但是如果您的圆圈在调整视图大小时变得锯齿状,这可能是因为插值质量。

您是否尝试将插值质量设置为高?

    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);

【讨论】:

感谢您的想法,但没有运气。 CGContextSetInterpolationQuality 无效。我也试过 CGContextSetFlatness 也没有效果。

以上是关于CALayer 中的抗锯齿绘图的主要内容,如果未能解决你的问题,请参考以下文章

画布中的抗锯齿大文本

paintComponent() 方法中的抗锯齿

游戏中的抗锯齿技术Anti-Alasing提炼总结

透明位图上的抗锯齿文本

基于图片的抗锯齿方法

Pixelart 的抗锯齿算法