BDGapps
BDGapps

Reputation: 3356

iPhone Quartz Drawing Eraser

I am trying to make an iPhone application with erasing. I am running into 2 problems, if you have a solution for either one please answer this. I would like to erase part of an image.

1) I am currently just clearing the rect but it has a square edge. I would like it to be round, I have previously tried translating but this does not work. I also need it to translate/rotate as few times as possible to maintain the same performance.

2) In addition I wanted to know if there are any other ways of erasing. When erasing fast it is erasing ever 1/2 inch. Is there a way to stroke a path and clear the rect or something? Sorry if this is hard to understand.

CGRect circleRect = CGRectMake([touch CGPointValue].x, [touch CGPointValue].y, 25, 25);
CGContextClearRect(currentContext,circleRect);

enter image description here

Upvotes: 3

Views: 2843

Answers (2)

digitalHound
digitalHound

Reputation: 4444

I realize this is an older question but I thought I would expand on Eric Reids answer as I was trying to use his example outside of the drawRect method and had to modify it to get it to work with a context I created in a 'touchesMoved' method in a UIView subclass.

I call this method from 'touchesMoved' and pass it the CGPoint of the touch in the view I'm drawing in.

-(void) processEraseAtPoint:(CGPoint)point
{
    // setup a context with the size of our canvas view (the canvas view is the UIView instance I'm drawing into)
    UIGraphicsBeginImageContext(self.canvasView.bounds.size);

    // get a reference to the context we just created
    CGContextRef context = UIGraphicsGetCurrentContext();

    // draw the image we want to edit into this context (this is the image containing the drawing I want to erase part of)
    [self.canvasView.incrementalImage drawAtPoint:CGPointZero];

    // set our context options
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, self.canvasView.settings.brushDiameter);
    CGContextSetBlendMode(context, kCGBlendModeClear);

    // make the color clear since we're erasing
    CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);

    // start our path in this context
    CGContextBeginPath(context);

    // set our first point
    CGContextMoveToPoint(context, lastTouch.x, lastTouch.y);

    // draw from our last point to this point
    CGContextAddLineToPoint(context, point.x, point.y);

    // stroke this path (in this case it's clear so it will erase what's there)
    CGContextStrokePath(context);

    // set our incrementalImage in the canvasView with the updated image from this context
    // Note that in the canvasView 'drawRect' method I am calling 
    // '[self.incrementalImage drawInRect:rect]', so this new image will get drawn 
    // in my canvasView when I call 'setNeedsDisplay'
    self.canvasView.incrementalImage = UIGraphicsGetImageFromCurrentImageContext();

    // cleanup our context
    CGContextFlush(context);
    UIGraphicsEndImageContext();

    // set our last touch point for the next line segment
    lastTouch = point;

    // update our view
    [self.canvasView setNeedsDisplay];

}

Upvotes: 2

Eric Reid
Eric Reid

Reputation: 457

This code should do what you're looking for:

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, self.strokeWidth);
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);
CGContextBeginPath(context);
CGContextMoveToPoint(context, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y);
CGContextStrokePath(context);     
CGContextFlush(context);

The key points are

1) CGContextSetLineCap(context, kCGLineCapRound), which makes it round

2) CGContextSetBlendMode(context, kCGBlendModeClear) which clears the context.

Upvotes: 5

Related Questions