Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Graphics stroke width is inconsistent between lines & arcs?

The use case: I am subclassing UIView to create a custom view that "mattes" a UIImage with a rounded rectangle (clips the image to a rounded rect). The code is working; I've used a method similar to this question.

However, I want to stroke the clipping path to create a "frame". This works, but the arc strokes look markedly different than the line strokes. I've tried adjusting the stroke widths to greater values (I thought it was pixelation at first), but the anti-aliasing seems to handle arcs and lines differently.

Here's what I see on the simulator:

Uneven stroke image

This is the code that draws it:

CGContextSetRGBStrokeColor(context, 0, 0, 0, STROKE_OPACITY);
CGContextSetLineWidth(context, 2.0f);
CGContextAddPath(context, roundRectPath);
CGContextStrokePath(context);

Anyone know how to make these line up smoothly?

like image 691
makdad Avatar asked Dec 17 '10 18:12

makdad


2 Answers

… but the anti-aliasing seems to handle arcs and lines differently.

No, it doesn't.

Your stroke width is consistent—it's 2 pt all the way around.

What's wrong is that you have clipped to a rectangle, and your shape's sides are right on top of the edges of this rectangle, so only the halves of the sides that are inside the rectangle are getting drawn. That's why the edges appear only 1 px wide.

The solution is either not to clip, to grow your clipping rectangle by 2 pt on each axis before clipping to it, or to move your shape's edges inward by 1 pt on each side. (ETA: Or, yeah, do an inner stroke.)

like image 79
Peter Hosey Avatar answered Sep 30 '22 11:09

Peter Hosey


Just in case anyone is trying to do the same thing I am (round rect an image):

The UIImageView class has a property layer, of type CALayer . CALayer already has this functionality built-in (it WAS a little surprising to me I couldn't find it anywhere):

UIImageView *thumbnailView = [UIImage imageNamed:@"foo.png"];
thumbnailView.layer.masksToBounds = YES;
thumbnailView.layer.cornerRadius = 15.0f;
thumbnailView.layer.borderWidth = 2.0f;
[self.view addSubview:thumbnailView];

Also does the trick.

like image 27
makdad Avatar answered Sep 30 '22 12:09

makdad