Draw/Paint 喜欢 UIView 中贝塞尔曲线路径内的素描颜色
Draw/Paint like sketch color inside a bezier path in UIView
我正在借助 UIView 上的 UIBezier 路径绘制形状图层:
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.frame=CGRectMake(-view.frame.origin.x, -view.frame.origin.y, view.frame.size.width, view.frame.size.height);
pathLayer.path = path.CGPath;
pathLayer.strokeColor = [[UIColor blackColor] CGColor];
pathLayer.fillColor = [[UIColor clearColor] CGColor];
//pathLayer.fillColor = nil;
pathLayer.lineWidth = 6.0;
pathLayer.lineJoin = kCALineJoinBevel;
[view.layer addSublayer:pathLayer];
我想在那个 UIView 上绘制触摸点,为此我正在做 :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[touches anyObject];
CGPoint touchBeganPoint;
touchBeganPoint=[touch locationInView:self];
actionString=@"drawPencil";
previousPoint1 = [touch locationInView:self];
previousPoint2 = [touch locationInView:self];
currentPoint = [touch locationInView:self];
[self touchesMoved:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
previousPoint2 = previousPoint1;
previousPoint1 = currentPoint;
currentPoint = [touch locationInView:self];
[self calculateMinImageArea:previousPoint1 :previousPoint2 :currentPoint];
}
CGPoint midPoint(CGPoint p1, CGPoint p2) //helper function
{
return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
}
- (void)calculateMinImageArea:(CGPoint)pp1 :(CGPoint)pp2 :(CGPoint)cp
{
// calculate mid point
CGPoint mid1 = midPoint(pp1, pp2);
CGPoint mid2 = midPoint(cp, pp1);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, pp1.x, pp1.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 -= 20 * 1.5;
drawBox.origin.y -= 20 * 1.5;
drawBox.size.width += 20 * 2.5;
drawBox.size.height += 20 * 2.5;
UIGraphicsBeginImageContextWithOptions(drawBox.size, NO, 0);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
curImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// generate the if conditionover here and than check and draw over paths
[self setNeedsDisplayInRect:drawBox];
[[NSRunLoop currentRunLoop] runMode:NSRunLoopCommonModes beforeDate: [NSDate date]];
}
-(void)drawRect:(CGRect)rect
{
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
[curImage drawAtPoint:CGPointMake(0, 0)];
CGContextRef context = UIGraphicsGetCurrentContext();
CALayer *layer=[self.layer.sublayers objectAtIndex:0];
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineWidth(context, 20);
CGContextSetStrokeColorWithColor(context,[UIColor redColor].CGColor);
CGContextSetShouldAntialias(context, YES);
CGContextSetAllowsAntialiasing(context, YES);
CGContextSetFlatness(context, 1.f);
CGContextSetAlpha(context,1.0);
CGContextStrokePath(context);
[super drawRect:rect];
}
现在,当我在 self.layer 上绘图时,它仍在影响添加的子层(形状层)。我只想在这条路径内绘制,不能使用 [path containspoint..] ,如绘制矩形,我正在绘制的图像有一些宽度,它有时会穿过路径或扰乱它的笔画。
实现这一点的一种方法是用它的子层(CAShapelayer)剪辑 UIView,然后在 uiview 上再次绘制它(这将清除形状图层区域之外的背景)。但是找不到如何剪辑它CAShapeLayer.
任何关于如何顺利实现这一目标的建议或见解都可能会有很大帮助。
谢谢!
拍摄了另一张图像,它是具有所需路径的视图快照,并填充了选定的颜色。
比触摸移动称为 drawrect 使用相同的代码,只是 [UIColor colorWithPatternImage:img] 作为上下文的颜色。
我正在借助 UIView 上的 UIBezier 路径绘制形状图层:
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.frame=CGRectMake(-view.frame.origin.x, -view.frame.origin.y, view.frame.size.width, view.frame.size.height);
pathLayer.path = path.CGPath;
pathLayer.strokeColor = [[UIColor blackColor] CGColor];
pathLayer.fillColor = [[UIColor clearColor] CGColor];
//pathLayer.fillColor = nil;
pathLayer.lineWidth = 6.0;
pathLayer.lineJoin = kCALineJoinBevel;
[view.layer addSublayer:pathLayer];
我想在那个 UIView 上绘制触摸点,为此我正在做 :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[touches anyObject];
CGPoint touchBeganPoint;
touchBeganPoint=[touch locationInView:self];
actionString=@"drawPencil";
previousPoint1 = [touch locationInView:self];
previousPoint2 = [touch locationInView:self];
currentPoint = [touch locationInView:self];
[self touchesMoved:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
previousPoint2 = previousPoint1;
previousPoint1 = currentPoint;
currentPoint = [touch locationInView:self];
[self calculateMinImageArea:previousPoint1 :previousPoint2 :currentPoint];
}
CGPoint midPoint(CGPoint p1, CGPoint p2) //helper function
{
return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
}
- (void)calculateMinImageArea:(CGPoint)pp1 :(CGPoint)pp2 :(CGPoint)cp
{
// calculate mid point
CGPoint mid1 = midPoint(pp1, pp2);
CGPoint mid2 = midPoint(cp, pp1);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, pp1.x, pp1.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 -= 20 * 1.5;
drawBox.origin.y -= 20 * 1.5;
drawBox.size.width += 20 * 2.5;
drawBox.size.height += 20 * 2.5;
UIGraphicsBeginImageContextWithOptions(drawBox.size, NO, 0);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
curImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// generate the if conditionover here and than check and draw over paths
[self setNeedsDisplayInRect:drawBox];
[[NSRunLoop currentRunLoop] runMode:NSRunLoopCommonModes beforeDate: [NSDate date]];
}
-(void)drawRect:(CGRect)rect
{
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
[curImage drawAtPoint:CGPointMake(0, 0)];
CGContextRef context = UIGraphicsGetCurrentContext();
CALayer *layer=[self.layer.sublayers objectAtIndex:0];
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineWidth(context, 20);
CGContextSetStrokeColorWithColor(context,[UIColor redColor].CGColor);
CGContextSetShouldAntialias(context, YES);
CGContextSetAllowsAntialiasing(context, YES);
CGContextSetFlatness(context, 1.f);
CGContextSetAlpha(context,1.0);
CGContextStrokePath(context);
[super drawRect:rect];
}
现在,当我在 self.layer 上绘图时,它仍在影响添加的子层(形状层)。我只想在这条路径内绘制,不能使用 [path containspoint..] ,如绘制矩形,我正在绘制的图像有一些宽度,它有时会穿过路径或扰乱它的笔画。
实现这一点的一种方法是用它的子层(CAShapelayer)剪辑 UIView,然后在 uiview 上再次绘制它(这将清除形状图层区域之外的背景)。但是找不到如何剪辑它CAShapeLayer.
任何关于如何顺利实现这一目标的建议或见解都可能会有很大帮助。 谢谢!
拍摄了另一张图像,它是具有所需路径的视图快照,并填充了选定的颜色。
比触摸移动称为 drawrect 使用相同的代码,只是 [UIColor colorWithPatternImage:img] 作为上下文的颜色。