如何使用Core Graphics(用于手指画)创build浮雕效果或阴影效果

我有问题在我的绘图中实现“浮雕/阴影效果”。 手指画图function目前正在我的自定义UIView工作正常,下面是我的drawRect方法代码:

用所有方法编辑代码:

 - (void)drawRect:(CGRect)rect { CGPoint mid1 = midPoint(previousPoint1, previousPoint2); CGPoint mid2 = midPoint(currentPoint, previousPoint1); CGContextRef context = UIGraphicsGetCurrentContext(); [self.layer renderInContext:context]; CGContextMoveToPoint(context, mid1.x, mid1.y); CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetLineWidth(context, self.lineWidth); CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor); CGContextSaveGState(context); // for shadow effects CGContextSetShadowWithColor(context, CGSizeMake(0, 2),3, self.lineColor.CGColor); CGContextStrokePath(context); [super drawRect:rect]; } CGPoint midPoint(CGPoint p1, CGPoint p2) { return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5); } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; previousPoint1 = [touch previousLocationInView:self]; previousPoint2 = [touch previousLocationInView:self]; currentPoint = [touch locationInView:self]; [self touchesMoved:touches withEvent:event]; } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; previousPoint2 = previousPoint1; previousPoint1 = [touch previousLocationInView:self]; currentPoint = [touch locationInView:self]; // calculate mid point CGPoint mid1 = midPoint(previousPoint1, previousPoint2); CGPoint mid2 = midPoint(currentPoint, previousPoint1); CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, mid1.x, mid1.y); CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); CGRect bounds = CGPathGetBoundingBox(path); CGPathRelease(path); CGRect drawBox = bounds; //Pad our values so the bounding box respects our line width drawBox.origin.x -= self.lineWidth * 2; drawBox.origin.y -= self.lineWidth * 2; drawBox.size.width += self.lineWidth * 4; drawBox.size.height += self.lineWidth * 4; UIGraphicsBeginImageContext(drawBox.size); [self.layer renderInContext:UIGraphicsGetCurrentContext()]; curImage = UIGraphicsGetImageFromCurrentImageContext(); [curImage retain]; UIGraphicsEndImageContext(); [self setNeedsDisplayInRect:drawBox]; } 

当我已经实现了这个我正在获得与点点的绘制效果…

看下面的图像(它没有任何阴影或浮雕效果)。 如果你有任何想法如何添加这些效果,请给我一些build议。 我该如何解决这个问题?

在这里输入图像说明

看来你正在创build数百甚至数千个单独的path,每个drawRect上都有一个path。 你用[self.layer renderInContext]这些弄平了,但是我不认为这是一个很好的解决方法。 相反,我想你想要做的是创build一个UIBezierPath来跟踪手指,追加path,并将UIBezierPath绘制到屏幕上。 如果你创build两个图层(或视图),你可以设置最上面的一个(透明)来“绘制”。 当用户抬起手指时,然后将整个UIBezierpath渲染到第二层(以及之前绘制的数据),并创build一个新的UIBezierPath来绘制下一个手指跟踪。 这样,当你跟踪某人的手指时,你只会更新一层(最上面的一层)。 这将有助于防止设备拖慢绘制太多path。

虽然,我会说,你目前的方法确实产生了一个很酷的“3D”效果。

我不确定是否浮雕,但是如果您想要将渐变阴影应用于逐渐更新的绘图,那么使用CALayers(链接到教程)将是一个不错的方法。 基本上,渐进绘图将更新透明图像(不会在此图像中绘制任何阴影),并且将此图像configuration为通过CALayer以阴影显示。

阴影是在边界上创build的,而且您正在绘制细小的线段,这会产生这种效果。 您需要创build一个path,然后再敲击一次。 这段代码可能会帮助你:)

 for (int i=0; i<[currentPath count]; i++) { CGPoint mid1 = [[self midPoint:[currentPath objectAtIndex:i+1] :[currentPath objectAtIndex:i]] CGPointValue]; CGPoint mid2 = [[self midPoint:[currentPath objectAtIndex:i+2] :[currentPath objectAtIndex:i+1]] CGPointValue]; CGContextMoveToPoint(context, mid1.x, mid1.y); CGContextAddQuadCurveToPoint(context, [[currentPath objectAtIndex:i+1] CGPointValue].x, [[currentPath objectAtIndex:i+1] CGPointValue].y, mid2.x, mid2.y); CGContextSetShadow(context, CGSizeMake(-2, -2), 3); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetStrokeColorWithColor(context,[color CGColor]); CGContextSetLineWidth(context, linewidth); i+=2; } CGContextStrokePath(context); 

尝试这种方式..这解决了可能会解决您的问题。首先创build你的path,并在完全创build后,抚摸它。 发生这种情况是因为在每一个小笔划中,因此创build的阴影会在其边界上形成一个点,所以您会得到这个效果。