iOS:抗锯齿失败(CALayer中的PNG)

时间:2011-08-14 11:04:46

标签: ios calayer antialiasing

我正试图在屏幕上绘制此图像:

src_image

这是代码:

        CALayer* dullLayer = [CALayer layer];
        {                
            dullLayer.frame = CGRectMake(0,0,BUTTON_SIZE,BUTTON_SIZE);

            dullLayer.position = CGPointFromPoint2D( btnCenter );

            dullLayer.opacity = topQuadrant ? 1.0 : 0.5;


            [wheelLayer addSublayer: dullLayer];
        }


        UIImage* test = [UIImage imageNamed: @"OuterButton_Dull.png"];

        dullLayer.contents = (id) [test CGImage];

这就是我得到的:

render_fail

是什么给出的?为什么边缘如此锯齿?将此与已完全以相同方式合成到屏幕的罗马数字图像形成对比。

我试过了

            dullLayer.edgeAntialiasingMask = 0x0f; // binary 1111

无济于事。

编辑:http://lists.apple.com/archives/cocoa-dev/2008/Feb/msg02070.html

3 个答案:

答案 0 :(得分:5)

如果您发布的结果图像与屏幕上显示的尺寸相同,那么您只是使用太大的图像。 PNG图像不是矢量图像,因此将其缩小将始终产生一些混叠;你进一步缩小它变得越糟糕。抗锯齿在这种情况下效果有限。

你没有看到数字图像的事实部分是因为它不像其他图像那样包含任何精细,高对比度的线条,部分原因可能是因为你正在使用较小的图像。

如果您将原始图像作为矢量图像,请尝试将其缩小到正确的大小,然后再将其转换为PNG。如果您在应用中的其他位置需要更高分辨率的版本,请考虑创建多个不同分辨率的PNG。

如果您没有将原始图像作为矢量图像,则应尝试查找替换图像。网上有一些免费剪贴画文件的好来源,例如http://www.openclipart.org/http://www.clker.com/

答案 1 :(得分:4)

我刚刚发了一篇文章:http://kellenstyler.com/?p=1360

如果您通过代码添加图像以及一些可以让您清理它的技巧,您可以做一些事情。

查看以下代码中的任何内容是否有帮助:

UIImage * img =[UIImage imageWithData:[NSData dataWithContentsOfFile:[[[NSBundle mainBundle ] resourcePath ] stringByAppendingPathComponent:@"AliasImage.png" ] ] ];
CGRect imageRect = CGRectMake( 0 , 0 , img.size.width + 4 , img.size.height + 4 );
UIGraphicsBeginImageContext( imageRect.size );
[img drawInRect:CGRectMake( imageRect.origin.x + 2 , imageRect.origin.y + 2 , imageRect.size.width - 4 , imageRect.size.height - 4 ) ];
CGContextSetInterpolationQuality( UIGraphicsGetCurrentContext() , kCGInterpolationHigh );
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[aliasImage setImage:img ];

aliasImage.transform = CGAffineTransformScale(aliasImage.transform , 0.45 , 0.45 );
aliasImage.layer.shouldRasterize = YES;
aliasImage.layer.rasterizationScale = 0.45;
aliasImage.layer.edgeAntialiasingMask = kCALayerLeftEdge | kCALayerRightEdge | kCALayerBottomEdge | kCALayerTopEdge;
aliasImage.clipsToBounds = NO;
aliasImage.layer.masksToBounds = NO;

答案 2 :(得分:2)

德斯蒙德已经钉了它。

似乎Apple框架中的抗锯齿只能在相邻像素上运行。因此,如果将图像缩小4倍,则像素0,0将与像素2,0平均,即像素1,0被完全丢弃。所以,如果你有锋利的边缘,这不会破坏它。

解决方案是将图像重复减少50%,直到它<1。 2倍所需的尺寸。

如果我逐步缩小原始600 x 600图像,每次将其减半,并将结果显示为256 x 256 CALayer,会发生以下情况:

progressive_reduction

第三张图片实际缩小到目标尺寸以下。奇怪的是,进一步缩小(其自动上升大小75-> 256以便显示)实际上看起来最好。

所以实际上在这种情况下,解决方案是将其减小直到它实际上小于所需的大小,然后让Apple的图形框架根据需要扩展它。