CALayer和CGGradientRef抗锯齿?

时间:2009-04-19 18:21:31

标签: iphone core-animation gradient antialiasing radial-gradients

对于iPhone的CALayer绘图我有一个奇怪的问题。我有一个根层,它添加了一堆代表“气泡”的子层。最终结果应该是这样的:

http://www.expensivedna.com/IMG_0018.PNG http://www.expensivedna.com/IMG_0018.PNG

问题在于我似乎无法将图层转换为抗锯齿(注意气泡上的锯齿)。我的代码覆盖bubble CALayer的drawInContext如下:

- (void)drawInContext:(CGContextRef)theContext{
CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);

size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.5,  // Start color
                          1.0, 1.0, 1.0, 0.0 }; // End color
CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef glossGradient = 
CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

CGPoint topCenter = CGPointMake(25, 20);
CGPoint midCenter = CGPointMake(25, 25);
CGContextDrawRadialGradient(theContext, glossGradient, midCenter, 20, topCenter, 10, kCGGradientDrawsAfterEndLocation); 

}

现在真正奇怪的是,如果我稍微改变绘图代码,只绘制正常的红色圆圈,如下所示:

- (void)drawInContext:(CGContextRef)theContext{
CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);

CGContextSetFillColorWithColor(theContext, [UIColor redColor].CGColor);
CGContextFillEllipseInRect(theContext, CGRectMake(0, 0, 40,40));
}

一切似乎都是抗锯齿好的:

http://www.expensivedna.com/IMG_0017.PNG http://www.expensivedna.com/IMG_0017.PNG

我似乎无法弄清楚这种看似奇怪的行为。我是否错过了抗锯齿渐变和普通圆圈之间的一些区别?

谢谢你们。

3 个答案:

答案 0 :(得分:4)

谢谢你们。事实证明,答案是你的两个答案(coob和Alex)的组合。基本上看起来CGDrawRadialGradient函数只在起始圆上有别名,而不是结尾。因为我想在两者上使用别名“edge”,所以我首先将函数设置为从内到外绘制,它处理第一个“边缘”,但产生以下内容:

Step 1

然后,我按照coob的建议剪辑图像,这会在泡泡的最后边缘产生一个漂亮的锯齿:

Step 2

看起来对我来说足够好了!

- (void)drawInContext:(CGContextRef)theContext{
CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);

size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.0,  // Start color
              1.0, 1.0, 1.0, 0.5 }; // End color
CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef glossGradient = 
CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

CGContextAddEllipseInRect(theContext, CGRectMake(5, 5, 40, 40));
CGContextClip(theContext);

CGPoint topCenter = CGPointMake(25, 20);
CGPoint midCenter = CGPointMake(25, 25);
CGContextDrawRadialGradient(theContext, glossGradient, topCenter, 10, midCenter, 20, kCGGradientDrawsAfterEndLocation);

}

答案 1 :(得分:2)

杰夫 - 让topCenter更进一步,并使用带有圆形遮罩的CGContextClipToMask。

编辑:实际上,更好的方法是使用CGContextClip使用矢量剪切路径。

编辑2:示例代码:

CGContextAddEllipseInRect(theContext, CGRectMake(20, 20, 10, 10));
CGContextClip(theContext);

在绘制渐变之前添加它,并将其绘制得更远。

答案 2 :(得分:0)

也许尝试退出kCGGradientDrawsAfterEndLocation?这可能是用alpha

做一些奇怪的事情
相关问题