【问题标题】:Undo & Redo w/o Storing Co-ords for Graphics在不存储图形坐标的情况下撤消和重做
【发布时间】:2014-03-03 23:29:06
【问题描述】:

我目前正在开发一个绘图程序,并且已经实现了撤消和重做方法,但是由于我的程序在用户绘图时速度变慢,我决定不将坐标存储在 ArrayList 中,而是直接将它们应用到缓冲图像。这种方法的问题是我不能像以前那样撤消或重做。 我在互联网上四处搜索,发现一个名为UndoManager 的类的引用。不过,我不知道如何将其应用于图形对象(鉴于我的情况)。

我仍然可以存储坐标,但这对我来说毫无用处,因为我直接在上面绘制它们,除非有人能想出一种方法来覆盖黑色线条和透明线条来替换它(目前,对于为此,我使用了 BufferedImage.setRGB(x,y,color),但这仅在我要替换的形状是圆形 (x^2 + y^2 = r^2) 或矩形时才有用。

有什么想法吗?

【问题讨论】:

  • 你是如何创建 ArrayList 的?您是否尝试过使用 LinkedList?
  • @MadProgrammer 我曾经使用过 AL,但是当我实现了橡胶工具(由于画布是透明的而必须使用 BuffImg.setPixel 而不是 G2D.drawLine)时,性能急剧下降,因为我必须为每次点击或拖动设置像素 rrpi 时间,其中 r 是可变的,包括所有其他笔划。
  • @MadProgrammer 我刚读了这个thread,发现LinkedList 比AL 慢。你问的原因是什么?
  • LinkedList 如果您不想要顺序访问,则速度较慢,它的增长能力更快,因为它不需要不断重新分配后备缓冲区,因此它不会创建很多需要被垃圾收集。正如我所看到的,您只是推送和弹出列表并运行线性访问(从列表的开头到结尾运行),LinkedList 实际上可能会给您带来更好的性能。
  • 您还可以减少撤消操作的概念,因此如果用户按下鼠标按钮并执行拖动操作,我会认为在释放鼠标之前,这将构成单个行动。作为一个想法,我可能更容易将您需要绘制的内容与被认为是“撤消”的操作区分开来

标签: java swing graphics graphics2d


【解决方案1】:

您可以保留您在上次操作中修改的内容的增量,并在撤消时应用该增量的倒数。

这就是我的意思:假设你有一个图像 A,你在它上面画了一条线,所以现在你有图像 B。如果你计算 C = A xor B 那么 C 是你刚刚做的增量的倒数。因此,您只需存储 C 即可进行撤消。撤消过程将是:A = B xor C

当然A、B、C不一定是完整的图像,它们可以只是变化的区域,并带有一些起点信息。

如果你想重做,那就是:B = A xor C

这背后的逻辑如下,请记住,将一个值与自身异或会产生 0,而将任何值与 0 异或会产生相同的数字。我将使用^ 作为xor 的缩写,就像您使用Java 一样。

如果你有一个连续 3 个像素的图像,具有 RGB 值:

A = [ (255,255,255) , (255,255,255), (255,255,255) ]

然后你用红色墨水在中间像素上画,你会得到:

B = [ (255,255,255) , (255,0,0), (255,255,255) ]

现在,通过对两个图像执行异或来计算增量:

C = [ (0,0,0) , (0,255,255), (0,0,0) ]

如果您想从 B 和 C 中获取 A,请执行 B xor C,即:

[ (255 ^ 0, 255 ^ 0, 255 ^ 0) , (255 ^ 0, 0 ^ 255, 0 ^ 255), (255 ^ 0, 255 ^ 0, 255 ^ 0) ]

这是原图:

`[ (255,255,255) , (255,255,255), (255,255,255) ]`

这里我使用了 255 和 0,因为这些数字具有易于计算的异或,但它适用于任何值。尝试 A = 127, B = 83 并计算 C 为 127^83,然后检查 A = B^C

希望对你有帮助。

【讨论】:

  • 对不起,我以前没有使用过二进制逻辑,所以你能向我解释一下吗,并且(如果可以的话)包括代码?谢谢。
  • 我修改了答案以添加更详细的解释。
  • 鉴于 OP 通过将点存储在 ArrayList 中而导致程序变慢的问题,我只能想象在每个图像之间存储字节增量只会产生相同的问题...但我确实喜欢这个主意 ;)
  • 好点。它不是明确的,但是:想法是将每个增量保存为 ArrayList 的一个元素,而不是将增量的每个点保存为一个元素。
  • 那么,还有其他想法吗? @MadProgrammer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-30
  • 2011-04-28
相关资源
最近更新 更多