在照片编辑应用程序中实现“撤消”功能的最佳方法是什么?

jsc*_*cul 4 java undo undo-redo

显然,存储更改历史的数组需要大量内存......这就是我的应用程序工作的方式,但似乎有一种更聪明的方法可以做到这一点。

ArrayList<Photo> photoHistory = new ArrayList<>();
photoHistory.add(originalPhoto);
photoHistory.add(change1);
photoHistory.add(change2);

// bad implementation - lots of memory
Run Code Online (Sandbox Code Playgroud)

也许只存储一个原始的和当前的视图模型并保留所使用的方法/过滤器的日志?然后当用户点击“撤消”时,它会取所做的更改总数并再次运行所有更改减去一?这似乎也非常低效。

我想我只是在寻找有关如何实现软件应用程序的一般“撤消”功能的建议。

Wol*_*ink 5

以下是 GIMP 如何实现它的提示:

GIMP 的 Undo 实现相当复杂。许多操作只需要很少的撤消内存(例如,更改图层的可见性),因此您可以在它们退出撤消历史记录之前执行较长的操作序列。某些操作(例如更改图层可见性)会被压缩,因此连续多次执行这些操作只会在撤消历史记录中生成一个点。但是,还有其他操作可能会消耗大量撤消内存。大多数过滤器是由插件实现的,所以 GIMP 核心没有有效的方法知道发生了什么变化。因此,除非在操作前后记住受影响层的全部内容,否则无法实现撤消。在它们退出撤消历史记录之前,您可能只能执行一些此类操作。

来源

因此,要尽可能做到最佳,您必须根据要撤消的操作执行不同的操作。显示或隐藏图层可以用微不足道的空间表示,但过滤整个图像可能需要存储整个图像的另一个副本。但是,如果您只过滤图像的一部分(或在图像的一小部分中绘制),也许您只需要存储那部分图像。