IOS: anti-aliasing failure (PNG in CALayer)

I am trying to make this screen image:

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:

render_fail

What gives? Why are the edges so jagged? Compare this to Roman digital images that were arranged to display in exactly the same way.

I tried

  dullLayer.edgeAntialiasingMask = 0x0f; // binary 1111 

to no avail.

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

+4
source share
3 answers

If the image of the result you posted is the same size as on the screen, you simply use the image too large. A PNG image is not a vector image, so scaling it will always give some aliases; further we go, worse it becomes. Smoothing will have a limited effect in such cases.

The fact that you don’t see it for digital images is partly explained by the fact that it does not contain any thin lines with high contrast, as another image does, and partly, it is possible because you use smaller images for them.

If you have the original image as a vector image, try scaling it to the desired size before converting it to PNG. If you need a higher resolution version somewhere else in your application, consider creating multiple PNGs, each with different resolutions.

If you do not have the original image as a vector image, try to find a replacement. There are several good sources for free online clip files, such as http://www.openclipart.org/ or http://www.clker.com/ .

+6
source

I just wrote a post about this: http://kellenstyler.com/?p=1360

There are a few things you can do if you add images through the code along with a few tricks that will allow you to clear it a bit more.

See if anything helps in the following code:

 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; 
+4
source

Desmond nailed it.

Smoothing in the Apple infrastructure seems to work only with neighboring pixels. therefore, if you reduce the image by 4x, a pixel of 0.0 will be averaged over a pixel of 2.0, i.e. pixel 1.0 is completely discarded. therefore, if you have sharp edges, this will not crack it.

The solution is to resize the image by 50% until it becomes <2x the desired size.

Here's what happens if I gradually reduce the original image to 600 x 600, halving it each time and showing a result of 256 x 256 CALayer:

progressive_reduction

The third image actually shrank below the target size. It is strange that further reduction (which automatically gets a size of 75 β†’ 256 for display) actually looks the best.

So, in this case, the solution was to reduce it until it was actually smaller than the required size, and then let Apple's graphics structure expand it as needed.

+2
source

All Articles