5

I have a custom UIView which is drawn using its -[drawRect:] method.

The problem is that the anti-aliasing acts very weird as black lines horizontal or vertical lines are drawn very blurry.

If I disable anti-aliasing with CGContextSetAllowsAntialiasing, everything is drawn as expected.

Anti-Aliasing:
alt text http://dustlab.com/stuff/antialias.png

No Anti-Aliasing (which looks like the expected result with AA):
alt text http://dustlab.com/stuff/no_antialias.png

The line width is exactly 1, and all coordinates are integral values.

The same happens if I draw a rectangle using CGContextStrokeRect, but not if I draw exactly the same CGRect with UIRectStroke.

mrueg
  • 8,185
  • 4
  • 44
  • 66

2 Answers2

10

Since a stroke expands equal amounts to both sides, a line of one pixel width must not be placed on an integer coordinate, but at 0.5 pixels offset.

Calculate correct coordinates for stroked lines like this:

CGPoint pos = CGPointMake(floorf(pos.x) + 0.5f, floorf(pos.y) + 0.5f);

BTW: Don't cast your values to int and back to float to get rid of the decimal part. There's a function for this in C called floor.

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
  • 2
    In addition to this, Apple provides some nice tips and sample code in the "Doing Pixel-Exact Drawing" section of the Cocoa Drawing Guide: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Transforms/Transforms.html#//apple_ref/doc/uid/TP40003290-CH204-BCICIJAJ – Brad Larson Sep 21 '09 at 16:32
  • here is simple way to avoid without any code at all http://www.techpaa.com/2012/06/avoiding-view-edge-antialiasing.html – ShivaPrasad Jun 18 '12 at 08:31
  • @jeeva `UIViewEdgeAntialiasing` is for edges of layers only. The question is about lines drawn in Quartz. Quartz drawing is not affected by `UIViewEdgeAntialiasing`. – Nikolai Ruhe Jun 20 '12 at 07:15
  • @Nikolai ya you are right UIViewEdgeAntialiasing has no effect on quartz drawing. – ShivaPrasad Jun 20 '12 at 08:46
0

in your view frames, you probably have float values that are not integers. While the frames are precise enough to do fractions of a pixel (float), you will get blurriness unless you cast to an int

CGRect frame = CGRectMake((int)self.frame.bounds..., (int)...., (int)...., (int)....);
coneybeare
  • 33,113
  • 21
  • 131
  • 183