IOS Quartz / CoreGraphics drawing perforated stroke

I draw a path in a CGContext, following a set of points collected from the user. It seems that some kind of random input jitter causes some edges of the line to appear jagged. I think a small pen will solve this problem. If I were using OpenGL ES, I would just apply a pen to the sprite with which I am stroking the path; however, this project requires me to stay in Quartz / CoreGraphics, and I cannot find a similar solution.

I tried to draw 5 lines, each line is a little bigger and more transparent to bring the pen closer. This leads to poor results and significantly slows down the work.

This is the line drawing code:

CGContextMoveToPoint(UIGraphicsGetCurrentContext(),((int)lastPostionDrawing1.x), (((int)lastPostionDrawing1.y))); CGContextAddCurveToPoint(UIGraphicsGetCurrentContext(), ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, lastPostionDrawing2.x, lastPostionDrawing2.y; [currentPath addCurveToPoint:CGPointMake(lastPostionDrawing2.x-((int)furthestLeft.x)+((int)penSize), lastPostionDrawing2.y controlPoint1:CGPointMake(ctrl1_x, ctrl1_y) controlPoint2:CGPointMake(ctrl2_x, ctrl2_y)]; 
+7
source share
1 answer

I am going to go ahead and assume that your CGContext still has anti-aliasing, but if not, it is obvious that the obvious will try first, as @Davyd notes: CGContextSetShouldAntialias is a function of interest.

Assuming not a problem, but a line smoothed out by context, but you still want something β€œsofter”. I can come up with a couple of ways to do this, which I hope will be faster than stroking 5 times.

Firstly, you can try to get the path (i.e., a path that describes the outline of the current path) using CGContextReplacePathWithStrokedPath , then you can fill this path with a gradient (or some other filling method will give the desired results.) This will be fine work for straight lines, but will not be straight for curved paths (since the gradient fills the area of ​​the stroked path and will be either linear or radial).

Another, perhaps less obvious, option is to overuse the CG shadow pattern for this purpose. The function you want to find: CGContextSetShadowWithColor Here is the method:

  • Save GState: CGContextSaveGState
  • Get bounding box of source path
  • Copy the path, translating it from yourself to 2.0 * bbox.width using CGPathCreateCopyByTransformingPath (note: use only the X direction, so you don't have to worry about flips in context)
  • Lock the context in the original bbox using CGContextClipToRect
  • Set the shadow in the context using CGContextSetShadowWithColor :
    • Some minimal blur (start at 0.5 and go from there. The blur parameter is non-linear, and IME is like guessing and checking).
    • An offset equal to -2.0 * the width of the bbox and 0.0 height is scaled to the base space. (Note: these offsets are in the base space. It will be crazy to understand, but assuming you are not adding your own scale transformations, the scale factor will be either 1.0 or 2.0, so, practically speaking, you will set offset.width from -2.0 * bbox.width or -4.0 * bbox.width)
    • Color of your choice.
  • Circle the translation path.
  • Put GState CGContextRestoreGState

This should leave you with a β€œjust” shadow that you can hope to adjust to achieve your desired results.

All that said, CG shadow performance pattern, IME, is less than completely amazing, and less than fully deterministic. I would expect it to be faster than stroking 5 times with 5 different strokes, but not in the vast majority.

It comes to how much it will cost you.

+2
source

All Articles