如何在iPhone上绘制透明的笔画(或者任何清晰的图像部分)
我有一个小应用程序,允许用户用手指在屏幕上绘制。 我有一个用户绘制的UIImageView
,通过创build一个CGContextRef
和各种CG draw
函数。 我主要用CGContextAddLineToPoint
函数绘制笔画/线条
现在我的问题是这样的:用户可以绘制各种颜色的线条。 我想给他能够使用"rubber"
工具来删除到目前为止绘制的图像的一部分,用手指。 我最初是通过使用白色的笔触(使用CGContextSetRGBStrokeColor
函数设置)做到这一点,但它没有解决…因为我后来发现UIImageView
上的UIImage
实际上有一个透明的背景,而不是白色的…所以我最终会得到一个白色的透明图像!
无论如何设置一个"transparent"
笔触颜色,或者有什么其他的方式来清除用户的手指下CGContextRef
的内容,当他移动它? 谢谢
这将做的伎俩:
CGContextSetBlendMode(context, kCGBlendModeClear)
我结束了使用Bresenham的线algorithm(当我必须编写自己的graphics程序的时候,回到了昔日的岁月)。
- (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); } } }
唷! 要创build一个(有些)笨重的橡皮擦线还有很长的路要走。
要使用它,请执行以下操作:
- (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]; }
这假定你已经创build了一个drawingView(UIImageView)和drawingBoard(UIImage)。
然后,要删除一行,只需执行如下操作:
CGContextRef ctx = UIGraphicsGetCurrentContext(); [self eraseStart]; [self contextEraseLine:ctx from:CGPointMake (x1, y1) to:CGPointMake (x2, y2) withThickness:10]; [self eraseEnd];
(用适当的值replacex1,y1,x2和y2)…
我试过使用:
CGContextSetStrokeColorWithColor (myContext, [[UIColor clearColor] CGColor]);
但是这不起作用,因为它似乎是在上下文中用不可见的颜色(以及不可见的颜色+绘制的颜色=绘制的颜色)“绘制”在上下文上。
我发现的唯一的解决scheme(这不是最佳的)是:
CGContextClearRect (myContext, CGRectMake(x, y, width, height));
不幸的是,这意味着你必须追溯一系列的反应,并自己生成线…
//erase part if(mouseSwiped) { //**************Working Code*************// UIGraphicsBeginImageContext(frontImage.frame.size); [frontImage.image drawInRect:CGRectMake(0, 0, frontImage.frame.size.width, frontImage.frame.size.height)]; CGContextSetLineCap(UIGraphicsGetCurrentContext(),kCGImageAlphaNone); //kCGImageAlphaPremultipliedLast); CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 10); CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1, 0, 0, 10); CGContextBeginPath(UIGraphicsGetCurrentContext()); CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); CGContextClearRect (UIGraphicsGetCurrentContext(), CGRectMake(lastPoint.x, lastPoint.y, 10, 10)); CGContextStrokePath(UIGraphicsGetCurrentContext()); frontImage.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); lastPoint = currentPoint; mouseMoved++; if (mouseMoved == 10) { mouseMoved = 0; } }
UIColor *clearColor = [UIColor clearColor];