【问题标题】:Performance issues with Java 2D when drawing bufferedimages绘制缓冲图像时 Java 2D 的性能问题
【发布时间】:2010-02-17 06:22:24
【问题描述】:

我正在设计一个 Canvas 对象,用于绘制大小为 228x262 像素的 BufferedImage。

该图像是使用 Graphics2D.drawImage(...) 方法绘制的。我正在给定的偏移范围内进行基于像素的颜色操作。以下代码示例:

for( int i = frameOffset; i < colorClock; i++ ) {  
    rgb[i] = new Color(this.colorBK).getRGB();  
    }

其中 rbg 设置为我要更改的缓冲图像。
问题是代码绘制速度很慢。

我正在使用 GraphicsConfiguration.createCompatibleImage 创建图像,并且我正在通过 Buffer Strategy 使用双缓冲。

请问有灯吗?

感谢adv。

【问题讨论】:

  • “绘画”是指RGB转换后吗?或者上述转换是否发生在每个渲染滴答上?
  • 您好,绘画循环发生在更新完成后。我首先更改给定像素的颜色,然后使用新的像素颜色更改 Graphics2D.drawImage。
  • 你试过分析它吗?你用的是什么IDE? NetBeans 有一个内置的分析器,我相信有一个 Eclipse 插件。

标签: java performance image rendering 2d


【解决方案1】:

如果每次绘制图像时都运行循环,则循环可能是瓶颈。有一个完全不必要的对象分配,这将使垃圾收集器经常运行。

我假设 colorBK 是 int。如果是这种情况,您只需创建并初始化一个 Color 对象并要求它返回一个分配给 rgb 数组的 rgb 值。实际发生的是您在 rgb 数组中分配了 colorBK 的值。因此,等效且更有效的实现将是 rgb[i] = colorBK。

为了进一步优化这一点,您可以将 colorBK 的值分配给最终的局部变量。这将避免一次又一次地获取字段的值。所以循环可能是这样的:

final int color = colorBK;
for( int i = frameOffset; i < colorClock; i++ ) {
    rgb[i] = color;
}

要获得更多的性能提升,您应该考虑是否有完全不同的方法可以做到这一点。由于上面的示例只是将一些像素更改为某种颜色,我可以假设这可以通过一个图像和几个 fillRects 来完成。

所以你可以用你想要的颜色填充图像后面的一个矩形(在本例中为 colorBK)。如果图像在这些区域中具有透明像素,则上述循环更改它们在画布中保持不变并获得相同的效果。这可能更有效,因为图形方法得到了更好的优化并且不涉及大量的数组使用。

【讨论】:

  • 正如其他人在此线程中指出的那样,如果颜色是恒定的,则只需在加载图像时执行一次,而不是在每次绘制期间执行一次。
  • 嗨劳里。其实图形方法应该更好,但是我之前已经用fillRects试过了,速度慢很多。但是由于现在的代码与当时的代码差别很大,所以我用 fillRects 代替了 BufferedImage 绘图,但性能保持不变。不过,我还没有尝试过后面的 fillRect 技巧,我会检查一下。谢谢你。可能我必须重新考虑整个绘图系统。
【解决方案2】:

不要仅仅为了为图像中的每个像素提取一个 RGB 整数而创建新颜色。我可以为 Color 找到的唯一单个参数构造函数是一个采用 int RGB 的构造函数——你不能直接使用 colorBK 吗?

另外,如果你在每幅画上都进行这种转换,那会很慢;您应该只需要进行一次转换。

【讨论】:

  • 您好猴子,感谢您的回复。实际上,我应该在执行一段代码后更改某些像素的颜色。我用来进行转换的颜色构造函数实际上是采用 int RGB 的颜色构造函数,但我做了一些更改,现在我可以直接使用了。只要底层的 getRGB() 对颜色分量的位进行一些转换,它就会返回一个与我传递给构造函数的值不同的值。但是在进行小的代码更改之后,我现在可以直接进行了。谢谢你。但仍然没有性能提升。
  • @Leonardo:该构造函数所做的唯一“更改”是使 alpha 值完全不透明:value = 0xff000000 | rgb;。这是您无需创建临时对象即可轻松完成的事情。
  • 简单的人,你是对的。就像我之前说的:“但是经过小的代码更改,我现在可以直接做。”。我的意思是我设法在没有任何临时对象的情况下做到了。对不起,我缺乏表达能力。此后我的观点是,即使没有临时工,我仍然会遇到性能问题。这是一个不大的 262x228 BufferedImage,但它需要足够的时间让我看到线条在绘图时被压扁。感谢您的回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
  • 2012-03-25
  • 2013-04-29
相关资源
最近更新 更多