Swick
Swick

Reputation: 177

Coloring/drawing code. How to make it more smooth with lower opacity? Remove brush points?

I have an iOS app with a coloring book type function. The code I use works for coloring. At full opacity the line quality looks ok but at a lower opacity you can see individual brush points.

Code:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    pointCurrent = [touch locationInView:self.view];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch = [touches anyObject];
    CGPoint pointNext = [touch locationInView:self.view];
    UIGraphicsBeginImageContext(img.frame.size);
    //    UIGraphicsBeginImageContext(img2.frame.size);
    [img.image drawInRect:CGRectMake(0, 0, img.frame.size.width, img.frame.size.height)];
    //  [img2.image drawInRect:CGRectMake(0, 0, img2.frame.size.width, img2.frame.size.height)];
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush);
    /// CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), a, b, c, d);
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), pointCurrent.x, pointCurrent.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), pointNext.x, pointNext.y);
    CGContextSetLineCap(UIGraphicsGetCurrentContext(),kCGLineCapRound);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    img.image = UIGraphicsGetImageFromCurrentImageContext();
    // img2.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    pointCurrent = pointNext;
}

result is: enter image description here

Upvotes: 1

Views: 146

Answers (1)

rmaddy
rmaddy

Reputation: 318824

The problem is that you update an image by drawing just the latest line segment on top of the image. Since the line color is partially transparent, you see the overlap of each segment.

The better option would be to create a UIBezierPath and keep adding each new segment to it. Then create a new image each time from the bezier path. This will eliminate the segment overlaps.

Something like this (not tested but should get you started):

Add an instance variable:

UIBezierPath *_path;

Then update your code:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint pointCurrent = [touch locationInView:self.view];
    _path = [[UIBezierPath alloc] init];
    _path.lineWidth = ... // set the width
    _path.lineCapStyle = ... // set the style
    _path.lineJoinStyle = ... // set the style
    [_path moveToPoint:pointCurrent];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint pointNext = [touch locationInView:self.view];
    [_path addLineToPoint:pointNext];

    UIGraphicsBeginImageContext(img.frame.size);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), a, b, c, d);

    [_path stroke];

    img.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

Upvotes: 1

Related Questions