在 Penultimate 和 iDraft 等绘画应用程序中撤消
在 iDraft 和 Penultimate 等应用程序中,它们可以很好地执行撤消和重做,没有任何延迟。
我尝试了很多方法。目前,我的测试应用程序在每次撤消后使用 [NSData writeToFile:atomically:] 将原始像素数据直接写入文件,但我得到了 0.6 秒的延迟。
谁能给出一些提示吗?
In apps like iDraft and Penultimate, they perform undos and redos very well without any delay.
I tried many approaches. Currently, my testing app writes raw pixel data directly to a file after each undo using [NSData writeToFile:atomically:] but I am getting 0.6s delay.
Can anyone give some hints on it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不知道 iDraft 也不了解 Penultimate,但很可能他们有比您更简单的绘图模型。在编写绘图应用程序时,您可以在两种基本的绘图表示形式之间进行选择:要么跟踪原始像素,要么跟踪线条、圆等绘图对象。 (或者,换句话说,您可以在像素表示和矢量表示之间进行选择。)
当您使用矢量进行绘制时,您不会跟踪各个像素。相反,您知道在给定宽度、颜色和其他参数的 X 点和 Y 点之间应该有一条线。当您要绘制这样的表示时,您可以调用 Quartz 来绘制线条。在这种情况下,模型(绘图表示)由几个数字组成,占用的内存很少,因此您可以在内存中拥有单个绘图的多个版本,从而可以快速方便地撤消和重做。
I don’t know iDraft nor Penultimate, but chances are they have a simpler drawing model than you have. When writing a drawing app you can choose between two essential drawing representations: either you track raw pixels, or you track drawing objects like lines, circles and so on. (Or, in other words, you choose between pixel and vector representation.)
When you draw using vectors, you don’t track the individual pixels. Instead you know there should be line between points X and Y of given width, color and other params. And when you are to draw such a representation, you call Quartz to stroke the line. In this case the model (the drawing representation) consists of a few numbers, takes little memory and therefore you can have many versions of a single drawing in a memory, allowing for a quick and convenient undo and redo.
将撤消堆栈保留在内存中。不要将每个操作都写入磁盘。无论您保留位图还是矢量,您的文件操作都不应该位于您执行的每个绘制操作的关键路径上。
如果您的数据模型是完整位图,请仅保留更改后的矩形以进行撤消/重做。
Keep your undo stack in memory. Don't write to disk for every operation. Whether you keep around bitmaps or vectors, your file ops shouldn't be on the critical path for every paint operation you do.
If your data model is full bitmaps, keep just the changed rect for undo/redo.
如前所述,您可能不需要为每个操作将数据写入磁盘,即使在基于像素的情况下也是如此,除非您尝试撤消全屏过滤器,您需要保留的只是边界矩形内包含的数据用户执行的画笔描边。
您可以对绘图进行双缓冲,即在绘制之前保留图像的副本,绘制到副本中,确定用户操作的边界矩形,复制并保留原始数据中的适当数据(带有大小和位置信息)。撤消时,您可以将该副本粘贴到修改的区域上。
此方法扩展到重做,撤消时获取要覆盖的区域并存储它。
As previously said, you probably don't need to write the data to disk for every operation, also in a pixel based case, unless you are trying to undo a full screen filter all you need to keep is the data contained within the bounding rectangle of the brush stroke that the user performed.
You can double buffer your drawing, i.e. keep a copy of the image before the draw, draw into the copy, determine the bounding rect of the user operation, copy and retain the appropriate data from the original (with size and location information). On undo you take that copy and paste it over the modified area.
This method extends to redo, on undo take the area that you are going to be overwriting and store it.