Java 与ImageIcon相比,BuffereImage速度非常慢

Java 与ImageIcon相比,BuffereImage速度非常慢,java,image,scala,swing,awt,Java,Image,Scala,Swing,Awt,我有这两个片段来加载图像并将其绘制到屏幕上。第一个使用swing的ImageIcon: import javax.swing.ImageIcon import java.awt.Image val g: Graphics2D = get_g2d() val img : Image = new ImageIcon("image.png").getImage() g.drawImage( img, 0, 0, 500, 500, // draw pos /

我有这两个片段来加载图像并将其绘制到屏幕上。第一个使用swing的ImageIcon:

import javax.swing.ImageIcon
import java.awt.Image

val g: Graphics2D = get_g2d()
val img : Image = new ImageIcon("image.png").getImage()
g.drawImage(
          img,
          0, 0, 500, 500,  // draw pos / size
          0, 0, 1024, 1024 // clip pos / size
          null)
第二个使用awt的BuffereImage:

import java.io.File
import java.awt.image.BufferedImage
import javax.imageio.ImageIO

val buf : BufferedImage = ImageIO.read(new File("image.png"))
val g: Graphics2D = get_g2d()
g.drawImage(
          buf.getSubImage(0, 0, 1024, 1024) // clip pos / size
          0, 0, 500, 500,  // draw pos / size
          null)
第一个使用ImageIcon的片段几乎立即加载,但如果我使用剪辑绘制它,它就不起作用(图像中的子帧用于制作精灵工作表)。只有当我删除剪辑参数(剪辑位置/大小)时,它才起作用,这使得无法将图像分割为精灵图纸

使用BuffereImage的第二个代码段在有剪辑和没有剪辑的情况下都能正确绘制。但是,加载大约需要5秒钟

我以为ImageIcon只是暂时加载了文件的低分辨率缓存图标,这可以解释即时加载的原因,但我将图像与这两种技术并排放置,它们完全相同

我可以将我的精灵表子图像分割为单独的图像,这样我就可以使用ImageIcon绘制它们,而无需剪裁它们,但我失去了将它们全部放在一个精灵表中的便利


我如何能像ImageIcon一样快速加载图像,但仍然具有剪辑支持?

很难从显示代码的方式看出您实际在做什么。您是否每次绘图时都在执行
ImageIO.read(新文件(“image.png”)
?如果是这样,那就是问题所在,或者说是你问题的一大部分。在初始化过程中,只加载一次图像,然后根据需要从中绘制子图像。@kshetline我正在做的唯一事情就是在那里显示。我加载一次图像,然后再绘制一次图像。就这样,没别的了。加载一次图像,然后再绘制一次,可能是你现在要做的全部,但你显然计划用这个做更多的事情。除非您打算使用图像绘制多个精灵,否则您不会谈论将图像用作精灵表,对吗?我的观点是,您应该将性能分为两部分:设置时间和每次使用执行时间。一旦你在一个真正的应用程序中使用它,后者将比前者重要得多,而不仅仅是编写几行测试代码。@kshetline是的,这是正确的。只是,我希望加载图像需要一段时间,因为它的分辨率很高,而ImageIcon几乎可以立即以相同的质量加载图像。我从未见过任何图像加载代码如此之快。我不明白它怎么能加载得这么快,为什么不能用作精灵表。我不认为
ImageIcon
会等待完全加载图像,它只是设置一个单独的线程开始加载图像,然后继续。
drawImage
的参数,您将其保留为
null
,这是一个
ImageObserver
——这实际上是确保在异步加载此类图像时更新这些图像所必需的。缓冲图像不需要它,因为它们在默认情况下完全渲染。