How to draw a transparent stroke (or anyway clear part of an image) on the iPhone How to draw a transparent stroke (or anyway clear part of an image) on the iPhone ios ios

How to draw a transparent stroke (or anyway clear part of an image) on the iPhone


This will do the trick:

CGContextSetBlendMode(context, kCGBlendModeClear)


I ended up using Bresenham's line algorithm (harkening back to the days of yore when I had to write my own graphics routines)...

- (void) contextEraseLine:(CGContextRef) ctx from:(CGPoint)startPoint to:(CGPoint) endPoint withThickness:(int)thickness {    int x, cx, deltax, xstep,    y, cy, deltay, ystep,    error, st, dupe;    int x0, y0, x1, y1;    x0 = startPoint.x;    y0 = startPoint.y;    x1 = endPoint.x;    y1 = endPoint.y;    // find largest delta for pixel steps    st = (abs(y1 - y0) > abs(x1 - x0));    // if deltay > deltax then swap x,y    if (st) {        (x0 ^= y0); (y0 ^= x0); (x0 ^= y0); // swap(x0, y0);        (x1 ^= y1); (y1 ^= x1); (x1 ^= y1); // swap(x1, y1);    }    deltax = abs(x1 - x0);    deltay = abs(y1 - y0);    error  = (deltax / 2);    y = y0;    if (x0 > x1) { xstep = -1; }    else         { xstep =  1; }    if (y0 > y1) { ystep = -1; }    else         { ystep =  1; }    for ((x = x0); (x != (x1 + xstep)); (x += xstep))    {        (cx = x); (cy = y); // copy of x, copy of y        // if x,y swapped above, swap them back now        if (st) { (cx ^= cy); (cy ^= cx); (cx ^= cy); }        (dupe = 0); // initialize no dupe        if(!dupe) { // if not a dupe, write it out            //NSLog(@"(%2d, %2d)", cx, cy);            CGContextClearRect(ctx, CGRectMake(cx, cy, thickness, thickness));    }        (error -= deltay); // converge toward end of line        if (error < 0) { // not done yet            (y += ystep);            (error += deltax);        }    }}

Phew! That's a long way to go to create a (somewhat) clunky eraser line.

To use it, do something like:

- (void)eraseStart {    // erase lines    UIGraphicsBeginImageContext(drawingBoard.size);    ctx = UIGraphicsGetCurrentContext();    CGContextDrawImage(ctx,CGRectMake(0,0,drawingBoard.size.width, drawingBoard.size.height),[drawingBoard CGImage]); }- (void)eraseEnd {    drawingBoard = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    [drawingView removeFromSuperview];    [drawingView release];    drawingView = [[UIImageView alloc] initWithImage:drawingBoard];    drawingView.frame = CGRectMake(intEtchX, intEtchY, intEtchWidth, intEtchHeight);    [self.view addSubview:drawingView];}

This assumes you have already created a drawingView (UIImageView) and drawingBoard (UIImage).

Then, to erase a line, simply do something like:

CGContextRef ctx = UIGraphicsGetCurrentContext();[self eraseStart];[self contextEraseLine:ctx from:CGPointMake (x1, y1) to:CGPointMake (x2, y2) withThickness:10];[self eraseEnd];

(replace x1, y1, x2, and y2 with appropriate values)...


I've tried using:

CGContextSetStrokeColorWithColor (myContext, [[UIColor clearColor] CGColor]);

but that doesn't work, because it seems to be "drawing" on top of the context with an invisible color (and invisible color + whatever color it is drawing on = the color it's drawing on).

The only solution I've found (which isn't optimal) is:

CGContextClearRect (myContext, CGRectMake(x, y, width, height));

Unfortunately, that means you have to trace a series of rects and generate the line yourself...