12

我正在尝试为移动设备(即有限版本的 Photoshop)编写位图编辑器。用户的文档由大约 4 个位图组成,每个位图大小约为 1000x500。

我想要一个尽可能简单的强大且高效的撤消/重做系统。我的目标是大约 0.2 秒来撤消或重做编辑。我正在寻找一些关于我当前预期方法的反馈或一些我可以使用的新想法。我认为我所拥有的太复杂了,所以我对继续进行持谨慎态度,所以只要知道这是我能做的最好的事情就很好了。

我已经为我的撤消/重做系统尝试了使用命令模式和备忘录模式的组合。到目前为止,我得出的一些结论是:

  1. 我没有足够的内存,并且我无法将内存写入磁盘的速度足够快,无法在许多情况下使用备忘录来支持对上一个命令的“未执行”操作,例如,如果用户非常快速地完成了几个单独的笔画,我不会能够存储代表用户绘制内容的位图,而无需让用户等待它们被保存。

  2. 如果我将文档恢复到其初始状态并重播除最后一个执行撤消的命令之外的所有命令,即使是适度数量的命令(例如重播 10 次油漆笔划或 5 次涂抹笔划也需要约 1 秒),这也太慢了迟缓。

  3. 我可以通过定期将整个文档在后台保存到磁盘并在播放命令之前恢复到此检查点来绕过前一点。要撤消比上一个检查点更远的位置,我们在此之前重新加载检查点并重播命令。

方法 2 和 3 可以正常工作,除了随着添加更多图层而保存整个文档变得越来越慢,并且使用 4 个位图(约 5 - 10 秒等待)已经很慢了。因此,我需要修改 3,以便只保存自上次以来更改的内容。

由于许多命令仅在一层上运行,因此仅保存自上一个检查点以来已修改的层是有意义的。例如,如果我有 3 个初始层,我已经指出了可能保存检查点的位置,那么我的命令堆栈可能看起来像这样。

(Checkpoint1: Save layer 1, 2 and 3.)
Paint on layer 1
Paint on layer 1
(Checkpoint2: Save layer 1. Reuse saved layers 2 and 3 from Checkpoint1.)
Paint on layer 2
Paint on layer 2
(Checkpoint3: Save layer 2. Reuse saved layers 1 and 3 from Checkpoint2.)
Paint on layer 3
Paint on layer 3
Flip layer 3 horizontally.
(Checkpoint4: Save layer 3. Reuse saved layers 1 and 2 from Checkpoint3.)
Resize layer 1, 2 and 3.
(Checkpoint5: Save layer 1, 2, 3.)

在编辑过程中,我会跟踪自上一个检查点以来哪些图层已被修改。当我恢复检查点时,我只恢复已更改的层,例如在修改第 2 层和第 3 层后恢复 Checkpoint4,我从磁盘重新加载第 2 层和第 3 层的备份。添加检查点时,我只保存到目前为止已修改的图层。我可以使所有这些大部分自动化,除非我的界面中需要用户被迫等待检查点被保存的地方,因为我一次只能在内存中保留大约 1 个图层的临时副本。

你怎么看?它比我希望的要复杂得多,但我看不到任何其他方式。还有其他有用的模式可以让我的生活更轻松吗?

4

2 回答 2

1

一种方法是将某些“框架”保留为完整的框架,而将其他“框架”保留为从前一个框架创建框架所必需的命令。你在#2 中提到了这一点。在内存中保留一些帧可能会有所帮助。

一个可能有助于平衡性能与可用于保存完整帧的空间/时间的技巧是丢弃一部分“旧”帧,以便在任何给定时间您可能具有来自例如 1、2、4 的撤消状态, 8、16、32 和 64 次操作前。撤消一个或两个操作将只需要读取一个帧。撤消三个将需要读取一个检查点并重复一个操作。撤消五个将需要读取一个检查点并重复三个操作。撤消 33 将需要读取检查点并重复 31 次操作。

为了提高应用程序的流畅性,在某些情况下,在撤消操作期间在后台重新计算检查点帧可能会有所帮助。例如,在撤消了 17 次操作之后,一个人可能会在后台开始计算从起点向后退 48、40 和 36 步的状态,因此如果想再往前走,那么他已经完成了一些工作。请注意,人们可能会丢弃返回 1、2、4、8 或 16 次操作的帧,因为可以通过从当前状态向前重播命令来重新创建它们。

于 2011-03-17T22:25:11.097 回答
1

以下对于使用图像的图层和撤消缓冲区可能很方便:

  • 将最新图像保留为图像
  • 以前的版本存储为与下一个版本的异或,然后(假设并非所有内容都以相同的方式更改或更改)使用简单的压缩算法(如运行长度编码)进行压缩

这具有以下优点

  • 以前的版本可以很容易地合并(异或在一起)。

这可能不适用于:

  • 颜色调整(色调、亮度等)
  • 坐标变换(裁剪、变形等)
于 2010-10-10T21:25:02.633 回答