在 UIImageView 上绘画具有更好的性能

发布于 2024-09-08 09:16:32 字数 1510 浏览 6 评论 0原文

我有一个视图,当用户在 iPad/iPhone 屏幕上移动手指时,我会在其中绘制一条虚线。我在存储为 LastLocation 的点和 CurrentLocation 点之间画了一条线。绘图应持久显示在屏幕上。 每次触发 touchMoved 事件时都会发生这种情况,最终让我在人们拖动手指的地方画一条虚线......就像绘画应用程序一样。

我有一个被调用的函数,它在触发触摸事件时执行以下操作。 该视图包含一个名为drawImage 的UIImageView。我使用 UIImageView 作为保留绘制线条的方法。这显然不是人们通常进行油漆应用的方式,因为它非常慢。 任何有关使用 CGContextRef 调用进行持久绘画的更好方法的见解将不胜感激。

/* Enter bitmap graphics drawing context */
UIGraphicsBeginImageContext(frame.size);
/* Draw the previous frame back in to the bitmap graphics context */
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)]; //originally self.frame.size.width, self.frame.size.height)];       
/* Draw the new line */
CGContextRef ctx = UIGraphicsGetCurrentContext();
/* Set line draw color to green, rounded cap end and width of 5 */
CGContextSetLineDash(ctx, 0, dashPattern, 2);
CGContextSetStrokeColorWithColor(ctx, color);
CGContextSetLineCap(ctx, kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
CGContextSetLineWidth(ctx, 5.0); // for size
/* Start the new path point */
CGContextMoveToPoint(ctx, LastLocation.x, LastLocation.y);
CGContextAddLineToPoint(ctx, Current.x, Current.y);
CGContextStrokePath(ctx);
/* Push the updated graphics back to the image */
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

“drawImage.image drawInRect”调用非常慢,并且本质上是重绘整个图像。

有没有更快的方法来做到这一点?我在博客上的一些地方看到过这样的绘图代码用于绘画,但它只是有点慢。 很想听听有关该主题的一些想法。

I have a view in which I paint a dotted line when the user moves their finger across the screen of the iPad/iPhone. I draw the line between a point stored as LastLocation, and the point that is the CurrentLocation. The drawings are to be persistant on the screen.
This happens every time the touchMoved event is fired, and ends up letting me draw a dotted line tracing where the person has dragged their finger.... just like a painting application.

I have a function that gets called that does the following when the touch event is fired.
The view contains a UIImageView called drawImage. I use UIImageView as a means of persisting the lines drawn. This clearly isnt how people usually do paint applications, as it is quite slow.
Any insight in to a better way to do persistant painting using the CGContextRef calls would be appreciated.

/* Enter bitmap graphics drawing context */
UIGraphicsBeginImageContext(frame.size);
/* Draw the previous frame back in to the bitmap graphics context */
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)]; //originally self.frame.size.width, self.frame.size.height)];       
/* Draw the new line */
CGContextRef ctx = UIGraphicsGetCurrentContext();
/* Set line draw color to green, rounded cap end and width of 5 */
CGContextSetLineDash(ctx, 0, dashPattern, 2);
CGContextSetStrokeColorWithColor(ctx, color);
CGContextSetLineCap(ctx, kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
CGContextSetLineWidth(ctx, 5.0); // for size
/* Start the new path point */
CGContextMoveToPoint(ctx, LastLocation.x, LastLocation.y);
CGContextAddLineToPoint(ctx, Current.x, Current.y);
CGContextStrokePath(ctx);
/* Push the updated graphics back to the image */
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

The 'drawImage.image drawInRect' call is extremely slow, and is in essence redrawing the entire image.

Is there a faster way of doing this? I have seen drawing code like this in a few places on blogs for painting, but it's just a bit slow.
Would love to hear some thoughts on the topic.

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

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

发布评论

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

评论(1

寄居者 2024-09-15 09:16:32

无需手动合成图像和线条。让在另一个绘制图像的 UIImageView 上方绘制线条的视图。让系统进行合成并绘制图像。

在您的代码中,只需在线条绘制视图的drawRect:方法中执行两条drawImage线条之间的操作即可。

-(void) drawRect:(CGRect)dirty {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    /* Set line draw color to green, rounded cap end and width of 5 */
    CGContextSetLineDash(ctx, 0, dashPattern, 2);
    CGContextSetStrokeColorWithColor(ctx, color);
    CGContextSetLineCap(ctx, kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
    CGContextSetLineWidth(ctx, 5.0); // for size
    /* Start the new path point */
    CGContextMoveToPoint(ctx, LastLocation.x, LastLocation.y);
    CGContextAddLineToPoint(ctx, Current.x, Current.y);
    CGContextStrokePath(ctx);
}

当线的一端移动时,保存新点并将线绘图视图标记为需要显示。因此 Current 和 LastLocation 都应该是线条绘制视图的成员,并且在每个的 setter 方法中调用 setNeedsDisplay。

确保对于线条绘制视图,clearsContextBeforeDrawing 为 YES,opaque 为 NO。

There is no need to composite the image and line manually. Have the view that draws the line above another UIImageView that draws the image. Let the system do the compositing and draw the image.

In your code, just do the stuff between the two drawImage lines in the drawRect: method of the line drawing view.

-(void) drawRect:(CGRect)dirty {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    /* Set line draw color to green, rounded cap end and width of 5 */
    CGContextSetLineDash(ctx, 0, dashPattern, 2);
    CGContextSetStrokeColorWithColor(ctx, color);
    CGContextSetLineCap(ctx, kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
    CGContextSetLineWidth(ctx, 5.0); // for size
    /* Start the new path point */
    CGContextMoveToPoint(ctx, LastLocation.x, LastLocation.y);
    CGContextAddLineToPoint(ctx, Current.x, Current.y);
    CGContextStrokePath(ctx);
}

When one end of the line moves, save the new point and mark the line drawing view as needing to display. So both Current and LastLocation should be members of the line drawing view, and in the setter method for each, call setNeedsDisplay.

Make sure clearsContextBeforeDrawing is YES and opaque is NO for the line drawing view.

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