is there an easy way to not draw this points in my lines?
I don't know why this points are there because i never release my finger from screen during drawing of a line.
I got the code from a drawing example.
// draw a line
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
currentPoint.y -= 0; // 20 only for 'kCGLineCapRound'
UIGraphicsBeginImageContext(self.view.frame.size);
//Albert Renshaw - Apps4Life
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)]; //originally self.frame.size.width, self.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brushSize); // for size
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), r, g, b, alpha); //values for R, G, B, and Alpha
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
mouseMoved++;
if (mouseMoved == 10) {
mouseMoved = 0;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//Draw a dot
if(!mouseSwiped) {
UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)]; //originally self.frame.size.width, self.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brushSize);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), r, g, b, alpha);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
}
This is the final version with unique alpha, color, brushSize for every line:
- (void) updateDrawingBoard
{
UIGraphicsBeginImageContext(self.drawImage.bounds.size);
for ( NSDictionary *dict in paths ) {
UIBezierPath *p = (UIBezierPath*)[dict objectForKey:@"path"];
p.lineWidth = [[dict objectForKey:@"size"]floatValue];
[[UIColor colorWithRed:[[dict objectForKey:@"red"]floatValue]
green:[[dict objectForKey:@"green"]floatValue]
blue:[[dict objectForKey:@"blue"]floatValue]
alpha:[[dict objectForKey:@"alpha"]floatValue]] setStroke];
[p stroke];
}
[[UIColor colorWithRed:r green:g blue:b alpha:alpha] setStroke];
[path stroke];
self.drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.drawImage];
path = [[UIBezierPath bezierPath] retain];
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinBevel;
path.lineWidth = brushSize;
[path moveToPoint:touchPoint];
[self updateDrawingBoard];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.drawImage];
[path addLineToPoint:touchPoint];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
path,@"path",
[NSNumber numberWithFloat:r], @"red",
[NSNumber numberWithFloat:g], @"green",
[NSNumber numberWithFloat:b], @"blue",
[NSNumber numberWithFloat:alpha], @"alpha",
[NSNumber numberWithFloat:brushSize], @"size", nil];
[paths addObject:dict];
[path release];
path = nil;
[self updateDrawingBoard];
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.drawImage];
[path addLineToPoint:touchPoint];
[self updateDrawingBoard];
}
Freeform Shapes - also called organic shapes, are irregular and uneven shapes. Their outlines may be curved, angular, or a combination of both. Form - an element of art, means objects that have three dimensions.
The problem is that you are gradually accumulating the line by drawing into an image. Where the old line and the new line overlap, you see "dots" from the overdraw.
The solution is to accumulate your points in a path and draw the image afresh each time using that path. Since you will be drawing a single path, not multiple overlapping paths, you shouldn't see the dots.
Outline of code:
CGMutablePathRef
.CGPathAddLineToPoint
.CGContextAddPath
to add the line to the context, then fill or stroke as desired. You could also use CGContextDrawPath
.Alternatively, you can use UIBezierPath
instead of CGMutablePathRef
, in which case the steps are:
UIBezierPath
.-addLineToPoint:
to add lines to the path.-stroke
, -fill
, and similar to draw the path into the context.This is likely to be simpler if you are not accustomed to working with CoreGraphics directly.
I would drop the intermediate image and move this code into a view class (LineDrawView
or CanvasView
or something) rather than leaving the code in a view controller. Instead of updating an image, the view can just draw itself directly to the screene. The view would have methods to clear the path, undo strokes, and create an image of the path. The view controller would then use these to clear the canvas, undo lines, and save the drawing. You could enrich this later with functionality to configure the line style.
I have been trying to beat this problem for a few days, trying out Jeremy W. Sherman's answer that is probably a very good idea but was not feasable for my implementation.
In my drawing app, I could not get the alpha curves to blend into each other by constantly render the path, though the dots disappeared. If you just want a clean, alpha-colored path this is probably the way to go.
But I found a solution to this that was much simpler; these adjustments create a perfect, alpha-colored path in realtime with blending (think of it as a felt tip pen kind of style):
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapButt);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeMultiply);
Hope this helps anyone who's doing some simple CG painting in iOS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With