当缩放和绘制图像时,CGContextStrokePath无法工作

6

根据 touchesMoved: 方法,我正在绘制线条,通常情况下都很正常。但当我缩放图像并且进行绘制时,之前画的线条会发生位移,变得越来越模糊,最终消失。我尝试过使用 UIPinchGestureRecognizer 和简单地增加 myImageViewframe(仅针对多点触控事件),但无论哪种方式都会出现问题。下面是绘图的代码:

- (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
  }
}

以下是未放大的绘图:

输入图像说明

这是放大后显示问题的图像,红色箭头显示了在放大之前已经绘制过的线段(如前一幅图所示)。图像既模糊又错位:

输入图像说明

还可以注意到向末端绘制的线的一部分未受影响,并且该现象发生在向过去绘制的线中。我认为其原因是放大/缩小时失去了图像大小属性,这可能导致模糊和移位,但我不确定!

编辑- 我上传了一个简短的视频来展示发生了什么。它有点有趣...

编辑2- 这是一个关注此问题的样本单视图应用程序


我认为这可能与你正在绘制的视图的contentMode有关。尝试使用UIViewContentModeRedraw? - kevboh
我尝试为myImageViewdrawImage(两者都是UIImageView)设置它,但它没有起作用:(... - tipycalFlow
@kevboh,我已经上传了一个视频(并在答案中添加了),这可能会让你更好地了解问题... - tipycalFlow
我明白了,这很奇怪。抱歉我无法提供更多帮助 :/ - kevboh
@kevboh 没问题伙计...尝试过了还是谢谢你... - tipycalFlow
3个回答

4
我下载了你的项目,发现问题在于自适应大小。按照以下步骤可以解决问题: 第一步:注释掉第70行:
drawImage.frame = CGRectMake(0, 0, labOrderImgView.frame.size.width, labOrderImgView.frame.size.height);

在你的 touchesMoved 方法中。

步骤2。viewDidLoad方法中,当drawImagealloc时(第90行)添加一行代码:

drawImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

然后,该错误被修复。


1

我是这样实现这个行为的:

  1. 记住路径的所有坐标(模型)。
  2. 将路径绘制到imageView的临时子视图中。
  3. 当用户开始捏/缩放图像时 - 什么也不做,即路径将被iOS缩放。
  4. 在用户完成捏合缩放时 - 使用您的模型以正确的方式重新绘制路径。

如果将路径保存为图像,则会得到糟糕的缩放效果。 此外 - 不要直接将路径绘制到图像上 - 绘制到某些透明视图并在编辑结束时拼合它们。


实际上,糟糕的结果并不是在缩放时出现的。而是在我缩放后绘制时发生了这种奇怪的情况。请观看问题中的短视频以更好地理解。 - tipycalFlow
有一个问题:您是否检查drawImage和myImageView的框架是否相同:[drawImage.image drawInRect:CGRectMake(0, 0, myImageView.frame.size.width, myImageView.frame.size.height)]; - SVGreg
是的...事实上,在 touchesBegan 中,我确保-drawImage.frame = myImageView.frame - tipycalFlow
好的...我尝试通过在drawImage中绘制并将其添加为子视图,但仍然存在相同的问题... - tipycalFlow
我尝试了你的方法,但问题仍然存在。不过,保存这些点后来帮助我实现了撤销/重做效果,所以谢谢 :) - tipycalFlow
显示剩余4条评论

1

你总是在一个图像上下文中绘制与你的图像视图大小相同的内容 - 当你放大时,这当然会变得模糊,因为你没有适应更高的分辨率。相反,更明智的做法是创建一个UIBezierPath,并在touchesMoved方法中添加一条线(使用addLineToPoint:),然后通过[bezierPath stroke]在自定义的drawRect方法中绘制它。你也可以将一个CAShapeLayer作为图像视图的子视图添加,并将其path属性设置为之前创建的bezierPathCGPath属性。

参见如何在iOS中用手指绘制贝塞尔曲线?以获取示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接