I need to render UIBezierPaths without anti-aliasing and then save them as PNG to retain the full pixel representations (for example, not let JPEG muck the image up). I've tried calling the CG functions below just before stroking the UIBezierPaths, but it seems none have any effect on the resultant rendered image. The paths are still rendered with anti-aliasing (i.e. smoothed).
CGContextSetShouldAntialias(c, NO);
CGContextSetAllowsAntialiasing(c, NO);
CGContextSetInterpolationQuality(c, kCGInterpolationNone);
Any hits would be greatly appreciated.
When I use those options, it turns off antialiasing. On the left is with the default options. On the right, with your options.
This is easy to control if you're using a UIView
subclass. This is my drawRect
:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShouldAntialias(context, NO);
[[UIColor redColor] setStroke];
UIBezierPath *path = [self myPath];
[path stroke];
}
And to capture the screen, from How to take a screenshot programmatically
- (void)captureScreen
{
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(self.window.bounds.size);
[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:[self screenShotFilename] atomically:YES];
}
If you're using a CAShapeLayer
, then I don't think you can control the antialiasing on screen, because as the documentation says:
The shape will be drawn antialiased, and whenever possible it will be mapped into screen space before being rasterized to preserve resolution independence. However, certain kinds of image processing operations, such as CoreImage filters, applied to the layer or its ancestors may force rasterization in a local coordinate space.
But, regardless of the antialiasing on screen, if you want to have your snapshot of the screen not be antialiased, you can insert your CGContextSetShouldAntialias
into the captureScreen
routine:
- (void)captureScreen
{
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(self.window.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShouldAntialias(context, NO);
[self.window.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
[data writeToFile:[self screenShotFilename] atomically:YES];
}
Where are you getting c
from? Are you certain that c
refers to the same thing as UIGraphicsGetCurrentContext()
in the drawing cycle that you use [UIBezierPath stroke]
? It's difficult to tell from the above sample.
If you want to be certain that you're drawing to the same context that you're configuring, fetch the CGPath
from the UIBezierPath
, and draw it directly:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicGetCurrentContext();
CGPathRef path = [self.bezier CGPath];
CGContextSetShouldAntialias(context, NO);
CGContextAddPath(context, path);
CGContextStrokePath(context);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With