简体   繁体   English

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

[英]iOS: Antialiasing fail (PNG in CALayer)

I'm attempting to draw this image on screen:我正在尝试在屏幕上绘制此图像:

src_image

This is the code:这是代码:

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

This is what I get:这就是我得到的:

渲染失败

What gives?是什么赋予了? Why are the edges so jagged?为什么边缘这么锯齿? Contrast this with the Roman numeral images that have been composited to screen in exactly the same way.将此与以完全相同的方式合成到屏幕上的罗马数字图像进行对比。

I have tried我努力了

            dullLayer.edgeAntialiasingMask = 0x0f; // binary 1111

to no avail.无济于事。

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

If the result image that you posted is the same size as it appears on the screen then you are simply using too large an image.如果您发布的结果图像与屏幕上显示的大小相同,那么您只是使用了太大的图像。 A PNG image is not a vector image, so scaling it down will always give some aliasing; PNG 图像不是矢量图像,因此将其缩小总是会产生一些锯齿; the further you scale down the worse it gets.你缩小得越多,情况就越糟。 Antialiasing will have limited effect in such cases.在这种情况下,抗锯齿效果有限。

The fact that you don't see it for the numeral images is partly because it doesn't contain any fine, high contrast, lines like the other image does and partly perhaps because you are using smaller images for them.您在数字图像中看不到它的事实部分是因为它没有像其他图像那样包含任何精细、高对比度的线条,部分原因可能是您为它们使用了较小的图像。

If you have the original image as a vector image, try scaling that down to the right size before converting it to PNG.如果您将原始图像作为矢量图像,请在将其转换为 PNG 之前尝试将其缩小到正确的大小。 If you need a higher resolution version somewhere else in your app, consider creating multiple PNGs, each at different resolutions.如果您在应用程序的其他地方需要更高分辨率的版本,请考虑创建多个 PNG,每个 PNG 具有不同的分辨率。

If you don't have the original image as a vector image, you should try finding a replacement.如果您没有将原始图像作为矢量图像,则应尝试寻找替代图像。 There are a couple of good sources for free clip art files on the web, such as http://www.openclipart.org/ or http://www.clker.com/ . web 上有几个很好的免费剪贴画文件来源,例如http://www.openclipart.org/http://www.clker.com

I just did a post on this: http://kellenstyler.com/?p=1360我刚刚发了一个帖子: http://kellenstyler.com/?p=1360

There are a few things you can do if you add the images via code along with a few tricks that will allow you to clean it up a little more.如果您通过代码添加图像以及一些允许您进一步清理图像的技巧,您可以做一些事情。

See if anything in the following code helps:查看以下代码中的任何内容是否有帮助:

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;

Desmond has nailed it.戴斯蒙德成功了。

It seems that anti-aliasing in Apple's frameworks only operates on neighbouring pixels.苹果框架中的抗锯齿似乎只对相邻像素起作用。 so if you reduce an image by 4x, pixel 0,0 is going to be averaged against pixel 2,0 ie pixel 1,0 is completely discarded.因此,如果将图像缩小 4 倍,则像素 0,0 将与像素 2,0 进行平均,即像素 1,0 被完全丢弃。 so if you have sharp edges, this isn't going to hack it.所以如果你有锋利的边缘,这不会破解它。

The solution is to repeatedly reduce the image by 50% until it is < 2x the desired size.解决方案是反复将图像缩小 50%,直到小于所需大小的 2 倍。

Here is what happens if I progressively reduce the original 600 x 600 image, halving it each time, and displaying the result into a 256 x 256 CALayer:如果我逐渐缩小原始 600 x 600 图像,每次将其减半,并将结果显示到 256 x 256 CALayer 中,会发生以下情况:

渐进式减少

The third image has actually scaled down to below the target size.第三张图片实际上已经缩小到低于目标尺寸。 Strangely, a further diminution (which automatically gets up-sized 75 -> 256 in order to be displayed) actually looks best of all.奇怪的是,进一步缩小(自动放大 75 -> 256 以便显示)实际上看起来最好。

So actually in this case the solution was to reduce it until it is actually smaller than the desired size, and then let Apple's graphical framework expand it as necessary.所以实际上在这种情况下,解决方案是减小它直到它实际上小于所需的大小,然后让 Apple 的图形框架根据需要扩展它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM