Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing 1 pixel wide paths in iOS

I am drawing a path in my drawRect implementation on a UIView with:

CGContextSetLineWidth(context, 0.5);
CGContextStrokePath(context);

With anti-aliasing on on my CGContext, I can't seem to draw 1 px lines.

on

I tried turning antialiasing off with:

CGContextSetShouldAntialias(context, NO);

but then my corners look terrible:

off

How do I keep antialiasing on but stop this sub-pixel bluring of 1 pixel lines?

like image 416
chrism Avatar asked May 27 '12 11:05

chrism


2 Answers

When you draw a line in iOS, you specify the coordinates of a infinitely narrow line. The drawn line will then extend to both side of that line by half the stroke width.

If your infinitely narrow line has integer coordinates and is horizontal or vertical, the drawn line will be two pixels wide and gray instead of one pixel wide and black (with anti-aliasing). Without anti-aliasing, the line will be slightly moved but the corners look ugly.

To solve it, use coordinates in the middle of a pixel (e.g. 200.5 / 170.5) and turn anti-aliasing on.

like image 51
Codo Avatar answered Nov 13 '22 19:11

Codo


- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    CGFloat inset = 0.5 / [[UIScreen mainScreen] scale];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    // draw
    CGContextSetLineWidth(context, inset);
    CGContextSetStrokeColorWithColor(context, _lineColor.CGColor);
    CGContextMoveToPoint(context, inset, 0);
    CGContextAddLineToPoint(context, inset, CGRectGetHeight(rect));
    CGContextStrokePath(context);
    CGContextRestoreGState(context);
}
like image 10
Chengjiong Avatar answered Nov 13 '22 19:11

Chengjiong