Search code examples
iosobjective-calphacgcontexterase

How to LIGHTLY erase drawn path in cgcontext?


I managed to implement erase drawings on CGContext

 UIImageView *maskImgView = [self.view viewWithTag:K_MASKIMG];
    UIGraphicsBeginImageContext(maskImgView.image.size);
    [maskImgView.image drawAtPoint:CGPointMake(0,0)];
    float alp = 0.5;

    UIImage *oriBrush = [UIImage imageNamed:_brushName];

    //sets the style for the endpoints of lines drawn in a graphics context
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGFloat eraseSize = oriBrush.size.width*_brushSize/_zoomCurrentFactor;

    CGContextSetLineCap(ctx, kCGLineCapRound);
    CGContextSetLineJoin(ctx, kCGLineJoinRound);
    CGContextSetLineWidth(ctx,eraseSize);
    CGContextSetRGBStrokeColor(ctx, 1, 1, 1, alp);
    CGContextSetBlendMode(ctx, kCGBlendModeClear);


    CGContextBeginPath(ctx);
    CGContextMoveToPoint(ctx, lastPoint.x,lastPoint.y);

    CGPoint vector = CGPointMake(currentPoint.x - lastPoint.x, currentPoint.y - lastPoint.y);
    CGFloat distance = hypotf(vector.x, vector.y);
    vector.x /= distance;
    vector.y /= distance;

    for (CGFloat i = 0; i < distance; i += 1.0f) {
        CGPoint p = CGPointMake(lastPoint.x + i * vector.x, lastPoint.y + i * vector.y);
        CGContextAddLineToPoint(ctx, p.x, p.y);
    }

    CGContextStrokePath(ctx);

    maskImgView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    lastPoint = currentPoint;

Problem is, this TOTALLY erase anything. The alpha set in this function ( CGContextSetRGBStrokeColor(ctx, 1, 1, 1, alp);) seems to be ignored totally.

I want to erase just lightly and repeated erasing will then totally removes the drawing.

Any ideas?

EDIT: As per request, I add more details about this code: alp=_brushAlpha is a property delcared in this ViewController class. It ranges from 0.1 to 1.0. At testing I set it to 0.5. This drawing code is triggered by pan gesture recognizer (change state). It is basically following the finger (draw/erase by finger).


Solution

  • You've set the blending mode to clear. That ignores stroke color. You should play with the various modes a bit, but I suspect you want something like sourceAtop or maybe screen. See the CGBlendMode docs for full details.