0

I know this kind of post was asked a lot of time, but I searched a lot on Google and on this site too, without finding any solution, that's why I'm posting this question. I would like to undo my CGContext line that I draw, without using UIBezierPath or anything else. Is there a way ? Here is the code I use to draw:

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

UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:mainImageView];

UIGraphicsBeginImageContext(mainImageView.frame.size);
[mainImageView.image drawInRect:CGRectMake(0, 0, mainImageView.frame.size.width, mainImageView.frame.size.height)];

CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), dimension);

const CGFloat *components = CGColorGetComponents([color CGColor]);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), components[0], components[1], components[2], components[3]);

CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());

mainImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

lastPoint = currentPoint;}

Thanks.

2 Answers2

1

To add undo:

You can't reveal any info in an image once it's been painted over...

You'll either have to keep copies of the image each time it's changed (lots of memory, although this could be reduced perhaps by keeping just copies of the changed areas only) or, keep a record of the user's drawing steps and then replay them after an undo.

nielsbot
  • 15,922
  • 4
  • 48
  • 73
0

Since you're drawing into an image you can just null out the image and the visible line will be gone.

mainImageView.image = NULL;
// Or
mainImageView.image = originalImage; // Where originalImage is your background if you're using one.

Update

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint currentPoint = [touch locationInView:mainImageView];

    UIGraphicsBeginImageContext(mainImageView.frame.size);

    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), dimension);

    const CGFloat *components = CGColorGetComponents([color CGColor]);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), components[0], components[1], components[2], components[3]);

    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());

    // Add the line as a subView.
    [mainImageView addSubView:[[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]];
    UIGraphicsEndImageContext();

    lastPoint = currentPoint;

}

- (void)undoLastLine
{
    [mainImageView.subviews.lastObject removeFromSuperview];
}
Ryan Poolos
  • 18,421
  • 4
  • 65
  • 98
  • 2
    Undo doesn't work like that. I need to make disappear the last line that I draw, not all of them. – James Dhar Feb 07 '13 at 14:01
  • In that case you can't be drawing directly on the original. You need to draw in layers and keep track of each line yourself. The simply remove the necessary lines from the screen one at a time. – Ryan Poolos Feb 07 '13 at 14:15
  • I added some code. Just a bit of sudo code, haven't put it in xCode. But basically it adds each line as a subview on top of your image instead of *into* the image. Then you have an undo that removes the last subview. – Ryan Poolos Feb 07 '13 at 14:27
  • It's a really great idea and it works but it too slow in the process. I mean, it undo every touch made by the finger. Not the complete line, but every "pixel" of it, so it takes some time to undo all of it. – James Dhar Feb 07 '13 at 14:44
  • 1
    Well thats all it is, an idea. Its up to you to write some of your own code and make it work. I'm not gonna build the whole app for ya bud. – Ryan Poolos Feb 07 '13 at 14:48