缩放和绘制图像时 CGContextStrokePath 不起作用
我根据 touchesMoved:
方法绘制线条,通常效果很好。但当我放大图像并绘制时,之前绘制的线条都发生了位移,并且变得越来越模糊,最终消失了。我尝试使用 UIPinchGestureRecognizer
并简单地增加 myImageView
的 frame
(仅适用于多点触摸事件),但问题同时出现。这是绘制的代码:
- (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:
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:
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我下载了你的项目,发现问题是自动调整大小。以下步骤将解决该问题:
第 70 行:
第 1 步。注释
touchesMoved
方法中的。 第2步在
viewDidLoad
方法中alloc
之后添加一行代码(第90行):然后,修复了该错误。
I downloaded your project and I found the problem is of autoresizing. The following steps will solve it:
Step 1. Comment the line 70:
in your
touchesMoved
method.Step 2. Add one line of code after drawImage is
alloc
ed (line 90) inviewDidLoad
method:Then, the bug is fixed.
您总是只是绘制图像视图大小的图像上下文 - 这当然会变得模糊,因为放大时您不会适应更高分辨率。创建一个
UIBezierPath
UIBezierPath 会更明智。 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 (withaddLineToPoint:
) in thetouchesMoved
method, then draw it in a customdrawRect
method via[bezierPath stroke]
. You could also just add aCAShapeLayer
as a subview of the image view and set itspath
property to theCGPath
property of thebezierPath
you created earlier.See Drawing bezier curves with my finger in iOS? for an example.
我以下面的方式实现了这样的行为:
如果将路径保存为图像,则会导致缩放结果看起来很糟糕。
另外 - 不要直接绘制到图像的路径 - 绘制到一些透明视图并在编辑结束时将它们分割在一起。
I implemented behavior like this in next way:
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.