缩放和绘制图像时 CGContextStrokePath 不起作用

发布于 2025-01-05 22:13:19 字数 1908 浏览 3 评论 0原文

我根据 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-这是示例单视图应用程序专注于问题。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

总以为 2025-01-12 22:13:19

我下载了你的项目,发现问题是自动调整大小。以下步骤将解决该问题:

第 70 行:

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

第 1 步。注释touchesMoved 方法中的

第2步viewDidLoad方法中alloc之后添加一行代码(第90行):

drawImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

然后,修复了该错误。

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.

魔法唧唧 2025-01-12 22:13:19

您总是只是绘制图像视图大小的图像上下文 - 这当然会变得模糊,因为放大时您不会适应更高分辨率。创建一个 UIBezierPathUIBezierPath 会更明智。 code> 一次,只需在 touchesMoved 方法中向其添加一条线(使用 addLineToPoint:),然后通过自定义 drawRect 方法绘制它[bezierPath 描边]。您还可以添加一个 CAShapeLayer 作为图像视图的子视图,并将其 path 属性设置为 bezierPath 的 CGPath 属性 您之前创建的。

请参阅在 iOS 中用手指绘制贝塞尔曲线?了解例子。

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.

晨曦慕雪 2025-01-12 22:13:19

我以下面的方式实现了这样的行为:

  1. 您应该记住路径的所有坐标(模型)。
  2. 将路径绘制到 imageView 的临时子视图中。
  3. 当用户开始捏合/缩放图像时 - 不执行任何操作,即路径将由 iOS 缩放。
  4. 当用户完成捏合缩放时 - 使用模型以正确的方式重新绘制路径。

如果将路径保存为图像,则会导致缩放结果看起来很糟糕。
另外 - 不要直接绘制到图像的路径 - 绘制到一些透明视图并在编辑结束时将它们分割在一起

I implemented behavior like this in next way:

  1. You should remember all coordinates of your path (MODEL).
  2. Draw your path into temporary subview of imageView.
  3. When user starts pinch/zoom your image - do nothing, i.e path will be scaled by iOS
  4. In the moment when user has finished pinch zooming - redraw your path in correct way using your model.

If you save path as image you get bad looking scaling as result.
Also - do not draw path straight to image - draw to some transparent view and split them together at the end of editing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文