Java复制bufferedImage性能问题

时间:2011-10-31 22:21:43

标签: java performance awt

他ppl!

我正在写游戏。因为随着时间的推移没有太大的变化我去了缓冲板的部分(玩游戏的部分)并且不时地复制它。我在前台更改了内容,所以我仍然需要高fps。我也想要缩放,这里是乐趣开始的地方:为了节省内存,我重用了缓冲区。每当我缩放应用程序滞后,然后正常运行。

在剖析后,我带来了两个性能杀手:

  • 清除后备缓冲区(4000x4000像素,大约需要29毫秒。为了保持透明度,我使用g.fillRect)

  • 将缓冲区复制回真实图像(当然不是实时图像,但是再次从getBufferStrategy()复制)。这需要300毫秒,下一次大约150毫秒,然后从第三帧开始顺利运行。

澄清问题可能是一些代码。我按以下方式创建自己的缓冲区:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
GraphicsConfiguration config = device.getDefaultConfiguration();
image = config.createCompatibleImage(width, height,Transparency.TRANSLUCENT);

现在我将Buffer复制回Image的部分。请注意,我需要删除缓冲区的某些部分,这就是我进行最大参数调用的原因。

g.drawImage(image, vs.boardOffsetX, vs.boardOffsetY, targetWidth, targetHeight, 0, 0, sourceWidth, sourceHeight, null);

最后,对于我的另一个问题:我清除图像如下:

Graphics2D g = (Graphics2D) image.getGraphics();
Color transparent = new Color(0, 0, 0, 0);
g.setColor(transparent);
g.setComposite(AlphaComposite.Src);
g.fillRect(0, 0, image.getWidth(null), image.getHeight(null));

非常感谢你!已经坚持了很长一段时间。并且不要害羞地给我关于我的方法的风格建议:这是我对图形的第一次诚实尝试。

谢谢!

编辑:我真正不理解的部分是完全相同的操作需要非常不同的次数。只有AWT-Thread运行除了我的线程我得到两次~300ms,然后它下降到10μs!!!!这对于复制1600万像素非常快。 有谁知道这个效果?并且可能知道一种“预优化”这种行为的方法吗?

2 个答案:

答案 0 :(得分:2)

听到我无法真正解决问题,你可能会感兴趣。相反,我取消了最后一个缩放步骤,将最大缓冲区限制为2000x2000的大小,并消除了最严重的问题。缩放现在变得非常顺利(我为第一次drawImage调用测量了80ms。这仍然相当多,但由于视图变化很快,你没有真正注意到它。)

在我的研究中,我还发现我无法明确强制java创建所需大小的加速VolatileImages。这可能是问题 - 上帝知道为什么。我仍然想知道......

但是给同样问题的人提出一个最后的忠告:环游。

感谢您的帮助!

答案 1 :(得分:1)

不知道它是否对您有帮助,但我的应用程序使用System.arraycopy()复制得更快。

BufferedImage tmp = (BufferedImage) img;
int[] src = ((DataBufferInt) tmp.getRaster().getDataBuffer()).getData();
int[] dst = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
System.arraycopy(src, 0, dst, 0, dst.length);