Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CGContextStrokePath not working when zooming and drawing images

I'm drawing lines according to touchesMoved: method and normally it works fine. But when I zoom into the image and draw, the previously drawn lines are both displaced and keep getting more and more blurry, ultimately vanishing. I've tried using UIPinchGestureRecognizer and simply increasing the frame of myImageView (for multi-touch events only) but the problem occurs both ways. Here's the code for drawing:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
 NSArray *allTouches = [touches allObjects];
 int count = [allTouches count];
 if(count==1){//single touch case for drawing line
    UITouch *touch = [touches anyObject];   
    CGPoint currentPoint = [touch locationInView:myImageView];
    UIGraphicsBeginImageContext(myImageView.frame.size);
    [drawImage.image drawInRect:CGRectMake(0, 0, myImageView.frame.size.width, myImageView.frame.size.height)];
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.0);
    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    lastPoint = currentPoint;
 }
else{//multi touch case
   // handle pinch/zoom
  }
}

Here is the image drawn over without zooming:

enter image description here

And this is the image depicting the problem after zooming-in with the red arrow showing the segment that was already drawn before zooming-in (as shown in previous image). The image is both blurred and displaced:

enter image description here

It can also be noticed that a part of the line drawn towards the end is unaffected and the phenomenon occurs for lines drawn back in time. I believe the reason for this is that the image size attributes are being lost when I zoom in/out which probably causes the blur and shift, but I'm not sure about that!

EDIT- I've uploaded a short video to show what's happening. It's sort of entertaining...

EDIT 2- Here's a sample single-view app focussing on the problem.

like image 787
tipycalFlow Avatar asked Feb 14 '12 17:02

tipycalFlow


2 Answers

I downloaded your project and I found the problem is of autoresizing. The following steps will solve it:

Step 1. Comment the line 70:

drawImage.frame = CGRectMake(0, 0, labOrderImgView.frame.size.width, labOrderImgView.frame.size.height);

in your touchesMoved method.

Step 2. Add one line of code after drawImage is alloced (line 90) in viewDidLoad method:

drawImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Then, the bug is fixed.

like image 140
Yu-Wei Chang Avatar answered Oct 06 '22 02:10

Yu-Wei Chang


You are always just drawing to an image context the size of your image view - this of course gets blurry, as you do not adapt to a higher resolution when zoomed in. It would be more sensible to instead create a UIBezierPath once and just add a line to it (with addLineToPoint:) in the touchesMoved method, then draw it in a custom drawRect method via [bezierPath stroke]. You could also just add a CAShapeLayer as a subview of the image view and set its path property to the CGPath property of the bezierPath you created earlier.

See Drawing bezier curves with my finger in iOS? for an example.

like image 34
MrMage Avatar answered Oct 06 '22 02:10

MrMage