首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >撤销是有代价的:从「绘画过程回放」看记录单元的选择

撤销是有代价的:从「绘画过程回放」看记录单元的选择

原创
作者头像
PC电脑医生
发布于 2026-09-29 11:43:17
发布于 2026-09-29 11:43:17
420
举报

金山画王经典版 的卖点里,有一项和"画画"本身不太相干:

绘画过程回放——自动记录从第一笔涂鸦到完成作品的全过程,可以保存绘画步骤。

"保存绘画步骤"这个说法值得琢磨。

因为顺着一想就会发现:它能回放,说明它内部一直在记东西——而且记的不是"画面",是"动作"。

这件事和另一个更常用的功能是同一套东西:撤销。

一、它记的是"动作",不是"画面"

先把两种记法分清楚。

第一种记法:记结果。 每做完一步,就把整张画布拍一张"照片"存下来。撤销就是"把上一张照片放回来"。

第二种记法:记动作。 存下"用了什么笔、什么颜色、从哪里画到哪里、什么时间画的"。画布不存,需要的时候按记录重新画一遍。

"回放"这件事,只有第二种记法才做得到——因为回放要的不是最终画面,而是"中间每一笔是怎么来的"。

所以这条卖点其实透露了它的内部结构:

它维护的是一条操作记录,而不是一堆画面快照。

想通这一点,撤销的几个"怪现象"就好解释了。

二、撤销和回放,是同一套记录的两个方向

两者用的都是同一份东西——操作序列:

  • 撤销 = 从序列里把最后一个操作拿掉,反向应用它的效果
  • 回放 = 从头把序列里的操作正向重演一遍

方向相反,数据同源。

由此可以推出一件有意思的事:"能回放"往往不是单独做出来的功能,而是"用操作记录来管理"这种做法的副产品。

选了这套结构,回放几乎是顺手就能提供的;而如果一开始选的是"存快照",那回放就得从头再做一套。

所以这两个功能看起来是两件事,实际上是一件事的两面。

三、两条路线的取舍

  • 每一步的代价(记结果(快照):一整张画布;记动作(操作):一条记录(通常很小))
  • 内存增长(记结果(快照):步数 × 画布大小;记动作(操作):与笔迹长度相关)
  • 撤销实现(记结果(快照):直接放回上一张;记动作(操作):反向应用,或配合局部备份)
  • 回放(记结果(快照):需要另做;记动作(操作):天然具备)
  • 最难的地方(记结果(快照):内存;记动作(操作):不可逆的操作)

两种都不是"更好",而是把困难放在了不同位置。

"记结果"的困难在内存上:画布一大、步数一多,占用涨得很快。

"记动作"的困难在可逆性上:大部分绘画动作(画一笔、贴一个素材)是容易反向的——把"画上来"变成"擦下去"就行。但有些操作本质不可逆:

  • 把整张图做一次模糊
  • 整体调色、缩放
  • 把多个图层合并

这些操作没有一个简单的"反操作"——你没法用"撤销模糊"这种动作把它变回去,因为模糊已经把信息丢掉了。

于是这类软件通常只能退一步:在做这类操作之前,先偷偷记下"受影响那一块原来的样子",撤销时把那一块贴回去。

这就解释了一个常见体验:

为什么有些操作能撤,有些撤了就回不到原样。

差别不在"优先级",而在"这个操作有没有一个能反向执行的动作"。

四、另外三个常见现象

现象一:撤销步数总是有限的。

因为每一步都要占资源——无论走哪条路线,成本都不为零。

而且成本不是恒定的:画布越大、图层越多,每一步越"重"。 所以"把撤销步数调到很大"会直接反映在内存占用上,这不是保守,是换算关系。

现象二:想撤最后一笔,却一下子撤掉好几笔。

因为连续的操作常常被"合并"成一条记录。 这是为省记录做的合并——原理上省了空间,代价是撤销的粒度变粗了。

所以"撤销不够精细"和"记录占用太大"往往是同一个取舍的两面。

现象三:回放出来的效果,和当时画的不完全一样。

因为回放依赖"操作能被重复执行"。 只要某个操作的结果依赖于当时的状态(当时的颜色设置、当时的素材版本、时机相关的效果),重演时就可能出现偏差。

换句话说:回放要求操作是"可重复的",而现实中总有一部分操作只能"大致重复"。

五、老软件在这一层的特殊之处

这一点和它的年代有关——金山画王经典版 的默认值,正是当年硬件条件的产物。

当年机器的内存量级小得多,所以默认的撤销步数、画布尺寸都偏保守。"经典版"在这些默认值上尤其明显。

而这里有一个容易被忽略的换算关系:

画布尺寸翻倍,每一步的代价不是翻倍,而是四倍。

因为画布的像素数量是"长 × 宽"。 所以在大画布上,可用的撤销步数会掉得比预想的快得多——这也是老软件一放到大尺寸画布上就开始吃力、甚至直接报内存不足的原因。

在现代机器上,把步数调高是可行的(这也是它今天还能顺畅使用的原因之一),但那条换算关系没有变:画布和步数之间,始终是在同一份内存里做取舍。

六、按需求怎么选

  • 画坏了能退回去(需要的是什么:撤销栈够深即可;注意:画布越大,可用的步数越少)
  • 想回溯创作过程(需要的是什么:操作记录(回放);注意:记录的是动作,不是画面)
  • 中间过程以后还要改(需要的是什么:保存可再编辑的中间文件;注意:存成有损格式就回不去了)
  • 想永久留住"过程"(需要的是什么:导出回放或逐帧保存;注意:它记录的是步骤,不是视频)
  • 只是给孩子随手画(需要的是什么:默认设置就够;注意:不必去调步数上限)

第三行要特别提醒:"保存下来的作品"和"以后还能改的作品"是两回事。 页面上说作品可以存成图片格式——图片是给看的,不是给改的。如果希望以后还能继续编辑,要保留软件自己的工程文件。

七、按现象定位

  • 撤销几次就撤不动了(原因方向:撤销栈按步数上限截断;处理方向:调高上限,或接受这个限制)
  • 一撤撤掉好几笔(原因方向:连续操作被合并成一条记录;处理方向:属设计取舍)
  • 某个操作撤不回原样(原因方向:该操作不可逆;处理方向:只能在操作前另存一份)
  • 大画布上很快提示内存不足(原因方向:每步代价随画布面积增长;处理方向:缩小画布或降低步数)
  • 回放效果与当时有出入(原因方向:操作无法完全重复执行;处理方向:属机制限制)
  • 作品存成图片后再也改不了(原因方向:图片不是工程文件;处理方向:保留原始工程文件)
  • 想撤的步数很多但又怕卡(原因方向:步数与画布面积共同决定占用;处理方向:两者同时降)

八、小结

关于 金山画王经典版 这类绘画软件的"撤销"与"回放",记住四条:

  • "能回放"说明它记的是"动作"而不是"画面"——这也是为什么回放往往不是单独做的功能,而是这种结构的副产品
  • 撤销和回放是同一份操作记录的两个方向:一个反向应用,一个正向重演
  • "记动作"把困难从内存转移到了可逆性上:画一笔易于反向,整体模糊、调色、合并图层本质上不可逆——差别不在优先级,而在"有没有能反向执行的动作"
  • 每一步都有成本,而且成本随画布面积增长:画布尺寸翻倍,单步代价是四倍——所以"撤销步数"和"画布大小"始终是在同一份内存里做取舍

这里可以带走的经验是关于"记录单元"的:任何"可以退回去"的功能,都必须先回答一个问题——你记录的是什么?

记结果(快照)、记差异、还是记动作,这三种选择同时决定了三件事:占用多少空间、能退多远、以及能不能重放。

数据库的事务日志、编辑器的历史记录、部署的回滚点,面对的都是同一个选择——先定记录单元,再谈能撤销多少步;顺序反了,就会出现"想撤却撤不动"或者"空间开销大到不能接受"这两种都不想要的结果。

https://www.ijinshan.com/software/jshw.html?channel=4109

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、它记的是"动作",不是"画面"
  • 二、撤销和回放,是同一套记录的两个方向
  • 三、两条路线的取舍
  • 四、另外三个常见现象
  • 五、老软件在这一层的特殊之处
  • 六、按需求怎么选
  • 七、按现象定位
  • 八、小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档