【问题标题】:iOS: Antialiasing fail (PNG in CALayer)iOS:抗锯齿失败(CALayer 中的 PNG)
【发布时间】:2011-08-14 11:04:46
【问题描述】:

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

这是代码:

        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];

这是我得到的:

什么给了?为什么边缘这么锯齿?将此与以完全相同的方式合成到屏幕上的罗马数字图像进行对比。

我试过了

            dullLayer.edgeAntialiasingMask = 0x0f; // binary 1111

无济于事。

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

【问题讨论】:

    标签: ios calayer antialiasing


    【解决方案1】:

    如果您发布的结果图像与屏幕上显示的大小相同,那么您只是使用了太大的图像。 PNG 图像不是矢量图像,因此将其缩小总是会产生一些锯齿;你缩小得越多,情况就越糟。在这种情况下,抗锯齿效果有限。

    您在数字图像中看不到它,部分原因是它不像其他图像那样包含任何精细、高对比度的线条,部分原因可能是您为它们使用了较小的图像。

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

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

    【讨论】:

    • 谢谢!这正是正在发生的事情。我将在下面发布完整的答案。
    • PS 是的,数字是很多较小的图像
    【解决方案2】:

    我刚刚发了一个帖子: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;
    

    【讨论】:

      【解决方案3】:

      戴斯蒙德成功了。

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

      解决方案是反复将图像缩小 50%,直到小于所需大小的 2 倍。

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

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

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

      【讨论】:

        猜你喜欢
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-22
        • 1970-01-01
        • 1970-01-01
        • 2011-11-29
        • 1970-01-01
        相关资源
        最近更新 更多