GeneCode
GeneCode

Reputation: 7588

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).

Upvotes: 0

Views: 480

Answers (2)

Rob Napier
Rob Napier

Reputation: 299325

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.

Upvotes: 1

Marat Ibragimov
Marat Ibragimov

Reputation: 1084

You have a flag named clearsContextBeforeDrawing in UIView. if you set it to YES it will clear it before every draw. according to documentation

A Boolean value that determines whether the view’s bounds should be automatically cleared before drawing. When set to YES, the drawing buffer is automatically cleared to transparent black before the drawRect: method is called. This behavior ensures that there are no visual artifacts left over when the view’s contents are redrawn. If the view’s opaque property is also set to YES, the backgroundColor property of the view must not be nil or drawing errors may occur. The default value of this property is YES. If you set the value of this property to NO, you are responsible for ensuring the contents of the view are drawn properly in your drawRect: method. If your drawing code is already heavily optimized, setting this property is NO can improve performance, especially during scrolling when only a portion of the view might need to be redrawn.

Upvotes: 0

Related Questions