简体   繁体   中英

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

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; 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. If you need a higher resolution version somewhere else in your app, consider creating multiple PNGs, each at different resolutions.

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/ .

I just did a post on this: 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. 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.

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:

渐进式减少

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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