gpt4 book ai didi

java - 存储图形对象是个好主意吗?

转载 作者:IT老高 更新时间:2023-10-28 20:40:09 27 4
gpt4 key购买 nike

我目前正在用java编写一个绘图程序,旨在具有灵活和全面的功能。它源于我前一天通宵写的最后一个项目。正因为如此,它有大量的错误,我一直在一一解决(例如,我只能保存空文件,我的矩形没有正确绘制,但我的圆圈可以......)。

这一次,我一直在尝试将撤消/重做功能添加到我的程序中。但是,我无法“撤消”我所做的事情。因此,我想在每次触发 mouseReleased 事件时保存我的 BufferedImage 副本。但是,由于某些图像的分辨率为 1920x1080,我认为这样做效率不高:存储它们可能会占用千兆字节的内存。

我不能简单地用背景颜色绘制相同的东西以撤消的原因是因为我有许多不同的画笔,它们基于 Math.random() 进行绘制,并且因为有有许多不同的层(在一个层中)。

然后,我考虑将用于绘制的 Graphics 对象克隆到 BufferedImage。像这样:

ArrayList<Graphics> revisions = new ArrayList<Graphics>();

@Override
public void mouseReleased(MouseEvent event) {
Graphics g = image.createGraphics();
revisions.add(g);
}

我以前没有这样做过,所以我有几个问题:

  • 这样做我还会浪费无意义的内存吗,比如克隆我的 BufferedImages
  • 是否有其他方法可以做到这一点?

最佳答案

不,存储 Graphics 对象通常是个坏主意。 :-)

原因如下:通常,Graphics 实例是短暂的,用于在某种表面(通常是 (J)Component缓冲图像)。它保存这些绘图操作的状态,如颜色、笔触、比例、旋转等。但是,它不保存绘图操作或像素的结果

因此,它不会帮助您实现撤消功能。像素属于组件或图像。因此,回滚到“以前的”Graphics 对象不会将像素修改回以前的状态。

以下是一些我知道可行的方法:

  • 使用“链”命令(命令模式)来修改图像。命令模式非常适合撤销/重做(并在 Action 中的 Swing/AWT 中实现)。从原始开始依次渲染所有命令。优点:每个命令中的状态通常不是那么大,允许您在内存中有许多步骤的 undo-buffer。缺点:经过大量操作,变慢了……

  • 对于每个操作,存储整个 BufferedImage(就像您最初所做的那样)。优点:易于实现。缺点:你会很快耗尽内存。提示:您可以序列化图像,使撤消/重做占用更少的内存,但代价是更多的处理时间。

  • 上述的组合,使用命令模式/链的想法,但在合理的情况下使用“快照”(如 BufferedImages)优化渲染。这意味着您不需要为每个新操作从头开始渲染所有内容(更快)。还将这些快照刷新/序列化到磁盘,以避免内存不足(但如果可以的话,将它们保留在内存中,以提高速度)。您还可以将命令序列化到磁盘,以实现几乎无限的撤消。优点:如果做得好,效果很好。缺点:需要一些时间才能正确。

PS:对于以上所有,您需要使用后台线程(如 SwingWorker 或类似的)在后台更新显示的图像,将命令/图像存储到磁盘等,以保持响应式 UI。

祝你好运! :-)

关于java - 存储图形对象是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31370403/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com