Search code examples
ioscore-graphics

How to draw a sequence of lines with different opacities without blending overlaps but blending with the background?


I am trying to add basic pressure sensitivity to a drawing app. I am running into an issue when I try to draw strokes, where the opacity depends on the pressure - the point of overlap of the line segments blends the two lines, which creates darker spots:

enter image description here

This is my code:

CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, path.thickness);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);

for (Segment *segment in segments) {
    CGContextMoveToPoint(context, segment.start.x, segment.start.y);
    CGContextAddLineToPoint(context, segment.end.x, segment.end.y);
    CGContextSetAlpha(context, segment.alpha);
    CGContextStrokePath(context);
}

I want avoid the circles where the line caps meet, but still be able to have transparency over the background.

I have experimented with the context blend modes, but nothing is completely satisfactory - kCGBlendModeDestinationAtop gave me smooth lines, but there is an artifact at the very end of the line and I lose blending with the background.

The banding is not an issue.


Solution

  • In case anyone has the same problem, the way I solved it was to draw the line segments into CGLayer (Core Graphics layer - not Core Animation layer and not Core Graphics Transparency layer). I set the CGLayer context blend mode to DestinationAtop and then rendered the CGLayer in my real CGContext with normal blending. Worked like a charm.