被存储图形对象是个好主意? [英] Is storing Graphics objects a good idea?

查看:204
本文介绍了被存储图形对象是个好主意?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在使用Java语言编写画图程序,设计有灵活和COM prehensive功能的过程。它从我的最后一个项目朵朵,我前一天写了一夜。正因为如此,它有吨,吨错误,其中我已经解决一个一个(如我只能保存的文件,这将是空的,我的矩形没有得出正确的,但我的圈子做的...)。

I'm currently in the process of writing a paint program in java, designed to have flexible and comprehensive functionalities. It stemmed from my final project, that I wrote overnight the day before. Because of that, it's got tons and tons of bugs, which I've been tackling one by one (e.g. I can only save files that will be empty, my rectangles don't draw right but my circles do...).

这时候,我一直在试图撤销/重做功能添加到我的计划。但是,我不能撤销的东西,我已经做了。因此,我有一个想法,以节省的mouseReleased 事件被触发我的的BufferedImage 每次副本。然而,一些图像去1920x1080分辨率,我想这不会是有效的:它们存储可能会采取GB的内存

This time, I've been trying to add undo/redo functionality to my program. However, I can't "undo" something that I have done. Therefore, I got an idea to save copies of my BufferedImage each time a mouseReleased event was fired. However, with some of the images going to 1920x1080 resolution, I figured that this wouldn't be efficient: storing them would probably take gigabytes of memory.

其原因,为什么我不能简单地画同样的事情用背景色撤消,是因为我有很多不同的画笔,颜料它基于的Math.random(),并且由于有许多不同的层(单层)。

The reason for why I can't simply paint the same thing with the background colour to undo is because I have many different brushes, which paint based on Math.random(), and because there are many different layers (in a single layer).

然后,我认为克隆,我用画到的BufferedImage 图形的对象。像这样的:

Then, I've considered cloning the Graphics objects that I use to paint to the BufferedImage. Like this:

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

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

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

I haven't done this before, so I have a couple questions:


  • 请问我仍然这样做,就像克隆浪费无谓的记忆我的 BufferedImages

  • 是否有必要以不同的方式,我可以做到这一点?

推荐答案

没有,存储图形对象通常是一个坏主意。 : - )

No, storing a Graphics object is usually a bad idea. :-)

这里的原因:通常情况下,图形实例是短暂的,用于油漆或绘制到某种表面上(通常是(J )组件的BufferedImage )。它拥有这些绘图操作的状态,喜欢的颜色,中风,缩放,旋转等。然而,这并不持有的绘图操作或像素的结果的。

Here's why: Normally, Graphics instances are short-lived and is used to paint or draw onto some kind of surface (typically a (J)Component or a BufferedImage). It holds the state of these drawing operations, like colors, stroke, scale, rotation etc. However, it does not hold the result of the drawing operations or the pixels.

正因为如此,它不会帮助你实现撤消的功能。像素所属的组件或图像。因此,回滚到一个previous图形对象不会修改像素回到previous状态。

Because of this, it won't help you achieve undo-functionality. The pixels belongs to the component or image. So, rolling back to a "previous" Graphics object will not modify the pixels back to the previous state.

下面是一些方法,我知道的作品:

Here's some approaches I know works:


  • 使用一个命令的链(命令模式)来修改图像。 Command模式的工作原理非常好的与撤销/重做(和在Swing / AWT实现在动作)。渲染所有的命令序列,从原来的开始。优点:在每个命令的状态通常没有那么大,让你有在内存中撤消缓冲区许多步骤。缺点:经过大量的操作,它变得很慢...

  • Use a "chain" of commands (command pattern) to modify the image. Command pattern works very nice with undo/redo (and is implemented in Swing/AWT in Action). Render all commands in sequence, starting from the original. Pro: The state in each command is usually not so large, allowing you to have many steps of undo-buffer in memory. Con: After a lot of operations, it becomes slow...

对于每一个操作,存储整个的BufferedImage (如你本来)。优点:易于实施。缺点:你会耗尽内存快。提示:您可以序列图像,使得撤销/重做服用较少的内存,在更多的处理时间成本。

For every operation, store the entire BufferedImage (as you originally did). Pro: Easy to implement. Con: You'll run out of memory fast. Tip: You could serialize the images, making undo/redo taking less memory, at the cost of more processing time.

以上,使用命令模式/链理念的结合,但合理的优化与快照的渲染(如 BufferedImages )的时候。这意味着你将不再需要使一切从一开始就为每一个新的操作(快)。同时冲洗/序列化这些快照到磁盘上,避免运行内存(但如果你能保持在内存中,速度)。你也可以序列的命令到磁盘上,几乎无限撤消。临:做对的时候的伟大工程。缺点:。将需要一些时间得到正确

A combination of the above, using command pattern/chain idea, but optimizing the rendering with "snapshots" (as BufferedImages) when reasonable. Meaning you won't need to render everything from the beginning for each new operation (faster). Also flush/serialize these snapshots to disk, to avoid running out of memory (but keep them in memory if you can, for speed). You could also serialize the commands to disk, for virtually unlimited undo. Pro: Works great when done right. Con: Will take some time to get right.

PS:对于所有上述情况,你需要使用一个后台线程(如的SwingWorker 或类似)来更新所显示的图像,存储命令/图像磁盘等在后台,保持一个负责任的UI。

PS: For all of the above, you need to use a background thread (like SwingWorker or similar) to update the displayed image, store commands/images to disk etc in the background, to keep a responsive UI.

祝你好运! : - )

Good luck! :-)

这篇关于被存储图形对象是个好主意?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆