Core Graphics Outline Chart

I am drawing an arbitrary line with Core Graphics 4 pixels wide, now I would like this line to have a 1 pixel outline of a different color. I don't see any CG features that achieve this out of the box, but I'm looking for suggestions on how to do it. This is my existing code:

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 4.0);

CGPoint curPoint = [(NSValue*)[points objectAtIndex:0] CGPointValue];
CGContextMoveToPoint(context, curPoint.x, curPoint.y);

for( int i = 1; i < [points count]; i++ ) {
    curPoint = [(NSValue*)[points objectAtIndex:i] CGPointValue];
    CGContextAddLineToPoint(context, curPoint.x, curPoint.y);
    CGContextStrokePath(context);
    CGContextMoveToPoint(context, curPoint.x, curPoint.y);
}

      

This produces a single line. I would like to create a 4px line with a 1px line highlighting the 4px line like this:

+1


source to share


5 answers


iOS 5.0 has added a new feature CGPathCreateCopyByStrokingPath()

that does what you want.

Create CGPathRef

for the black path first and then create it with CGPathCreateCopyByStrokingPath()

.



This will give you a new path that you can fill with black and stroke with red to get what you want.

Also, path creation is a bit slower. You must avoid creating paths while running the screen drawing. All of your paths must be saved in RAM and ready to go before you start drawing on the screen. drawRect:

should only draw the path, not create it.

+5


source


Similar to what Abhi Beckert suggests, but you can use this function:

CGContextReplacePathWithStrokedPath(CGContextRef c);

      



which is also present in old SDKs - iOS 4.1, macOS X 10.6.
It's also better to create the entire path and then stroke it (or stroke and fill at the same time) at the end - in other words, you don't need to have a CGContextStrokePath inside the loop.

+1


source


I'm afraid you'll have to draw the path again with the line width set to 1. If you want it to be outside your 4-pixel path, you'll have to adjust your path accordingly.

Edit: Another option comes to you - you can iron the template - see Apple's QuartzDemo example.

0


source


To add an answer to my own question, this can be done by drawing a line a few pixels wider in the highlight color followed by the actual line on top. This creates an outline effect.

0


source


There is no built-in way to convert a stroke to a path and then stroke that path. However, you can get close to this by drawing the line twice: once in 6px increments (4px + 1 on each side) and then again in 4px increments in a different color

Similarly:

CGContextRef context = UIGraphicsGetCurrentContext();

CGPoint curPoint = [(NSValue*)[points objectAtIndex:0] CGPointValue];
CGContextMoveToPoint(context, curPoint.x, curPoint.y);

for( int i = 1; i < [points count]; i++ ) {
    curPoint = [(NSValue*)[points objectAtIndex:i] CGPointValue];
    CGContextAddLineToPoint(context, curPoint.x, curPoint.y);
}

// Set your 1 pixel highlight color here using CGContextSetRGBStrokeColor or equivalent
// CGContextSetRGBStrokeColor(...)
CGContextSetLineWidth(context, 6.0);
CGContextStrokePath(context);


// Set your 4 pixel stroke color here using CGContextSetRGBStrokeColor or equivalent
// CGContextSetRGBStrokeColor(...)
CGContextSetLineWidth(context, 4.0);
CGContextStrokePath(context);

      

Another idea would be to create a shadow via CGContextSetShadowWithColor (context, CGSizeZero, 1.0, yourHighlightColorHere) before drawing the stroke, although this will not draw the highlight color at full opacity. (I also can't remember if the shadows were shadow strokes - I only used them with fill)
-1


source







All Articles