disable anti-aliasing for UIBezierPath

core-graphics, ios

Solution

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

Problem

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.

Original source

Related problems