Java 中的 Graphics.drawImage() 在某些计算机上非常慢,但在其他计算机上要快得多
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/658059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Graphics.drawImage() in Java is EXTREMELY slow on some computers yet much faster on others
提问by DJClayworth
I'm having a strange problem, basically in Java Graphics.drawImage() is extremely slow on some computers and faster on others. This isn't related to the computers power either, some weaker computers run it fine while some stronger ones seem to choke up at the drawImage call.
我有一个奇怪的问题,基本上在 Java Graphics.drawImage() 在某些计算机上非常慢,而在其他计算机上则更快。这也与计算机功率无关,一些较弱的计算机运行良好,而一些较强的计算机似乎在 drawImage 调用时窒息。
It may or may not be related to the width and height, I have a very, very large width and height defined (something like 5000 by 2500). I wouldn't think it's the issue except like I said it runs in real time speed on some computers and slower on others and doesn't seem to be tied to the computers relative power.
它可能与宽度和高度有关,也可能不相关,我定义了一个非常非常大的宽度和高度(类似于 5000 x 2500)。我不认为这是问题所在,除非我说它在某些计算机上以实时速度运行而在其他计算机上运行速度较慢,并且似乎与计算机的相对功率无关。
Both computers have the same version of Java, both use Vista. One has a 1.83ghz Core 2 Duo with 1gb RAM and onboard graphics (runs everything fine), the other has a 2.53 ghz core 2 duo with a 9600GS (latest nVidia drivers) and 4gb of RAM and it literally chugs on the drawImage call.
两台计算机的Java 版本相同,都使用Vista。一个有一个 1.83ghz Core 2 Duo,带有 1gb RAM 和板载图形(运行一切正常),另一个有一个 2.53 ghz core 2 duo,带有 9600GS(最新的 nVidia 驱动程序)和 4gb 的 RAM,它在 drawImage 调用上确实很突兀。
Any ideas?
有任何想法吗?
edit: ok this is really wierd, I'm drawing the image to a window in Swing, now when I resize the window and make it really small the image gets scaled down too and it becomes small. Suddenly everything runs smoothly, when I scale it back up to the size it was before it's still running smoothly!
编辑:好的,这真的很奇怪,我正在将图像绘制到 Swing 中的窗口,现在当我调整窗口大小并使其非常小时,图像也会缩小并变小。突然间一切都运行顺利,当我将它放大到它仍然运行之前的大小时!
It also has multiple monitor issues, if I do the resize trick to make it run faster on one monitor then scroll it over to another monitor when more than half of the window is in the new monitor it starts chugging again. I have to resize the window again to small then back to its original size to get back the speed.
它也有多个显示器问题,如果我使用调整大小技巧使其在一台显示器上运行得更快,然后当超过一半的窗口在新显示器中时将其滚动到另一台显示器,它会再次开始卡顿。我必须再次将窗口大小调整为小,然后恢复到其原始大小以恢复速度。
If I do the resize trick on one monitor, move it over to the other it of course chugs, but if I return it back to the original monitor on which I did the resize trick it works 100%
如果我在一台显示器上执行调整大小技巧,将其移到另一台显示器上,它当然会发出声音,但是如果我将其返回到我执行调整大小技巧的原始显示器上,它可以 100% 工作
If I have two swing windows open (displaying the same image) they both run slow, but if I do the resize trick on one window they both start running smoothly (however this isn't always the case).
如果我打开了两个摇摆窗口(显示相同的图像),它们都运行缓慢,但是如果我在一个窗口上执行调整大小的技巧,它们都会开始平稳运行(但情况并非总是如此)。
*when I say resize the window I mean make it as small as possible to the point the image can't actually be seen.
*当我说调整窗口大小时,我的意思是让它尽可能小到实际上看不到图像的程度。
Could this be a bug in Java maybe?
这可能是Java中的错误吗?
回答by DJClayworth
Performance of writing an image to a screen is very much affected by the format in which the image is stored. If the format is the same as the screen memory wants then it can be very fast; if it is not then a conversion must be done, sometimes pixel by pixel, which is very slow.
将图像写入屏幕的性能很大程度上受图像存储格式的影响。如果格式与屏幕内存所需的格式相同,那么它可以非常快;如果不是,则必须进行转换,有时是逐像素转换,这非常慢。
If you have any control over how the image is stored, you should store it in a format that the screen is looking for. Here is some sample code:
如果您可以控制图像的存储方式,则应以屏幕正在寻找的格式存储它。下面是一些示例代码:
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
GraphicsConfiguration config = device.getDefaultConfiguration();
BufferedImage buffy = config.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
Graphics g = buffy.getGraphics();
If you are going to draw the image many times it may be worth converting to a compatible format even if it came in some other format.
如果您要多次绘制图像,即使它采用其他格式,也可能值得转换为兼容格式。
Drawing an image will also be slower if you are transforming it as you draw, which the 'resizing' part of your description makes me think you might be. Again, do the resize once (when the window is resized) and cache the resized and compatible image so that it can be redrawn quickly.
如果您在绘制时对其进行转换,则绘制图像也会变慢,您描述的“调整大小”部分让我认为您可能是这样。再次,调整大小一次(当调整窗口大小时)并缓存调整大小和兼容的图像,以便可以快速重绘。
回答by KitsuneYMG
If you are using sun's Java try some of the following system properties, either as command line parameters or the first lines in main
如果您使用的是 sun 的 Java,请尝试以下一些系统属性,作为命令行参数或 main 中的第一行
sun.java2d.opengl=true //force ogl sun.java2d.ddscale=true //only when using direct3d sun.java2d.translaccel=true //only when using direct3d
more flags can be viewed at this page
可以在此页面查看更多标志
Look at sun.java2d.tracewhich can allow you to determine the source of less-than-desirable graphics performance.
查看sun.java2d.trace哪些可以让您确定不理想的图形性能的来源。
回答by schnaader
There are several things that could influence performance here:
有几件事可能会影响这里的性能:
- Available RAM
- CPU speed
- Graphic card (onboard or seperate)
- Graphic driver
- Java version
- Used video mode (resolution, bitdepth, acceleration support)
- 可用内存
- CPU速度
- 显卡(板载或独立)
- 图形驱动程序
- 爪哇版
- 使用的视频模式(分辨率、位深度、加速支持)
EDIT: Having a look at the edited question, I'd propose to check if the 9600GS system has the newest NVIDIA drivers installed. I recently installed a driver for an Intel onboard graphics card that replaced the generic Windows driver and made moving windows, watching videos, browsing etc. a lot faster.
编辑:查看已编辑的问题,我建议检查 9600GS 系统是否安装了最新的 NVIDIA 驱动程序。我最近为英特尔板载显卡安装了一个驱动程序,它取代了通用的 Windows 驱动程序,并使移动窗口、观看视频、浏览等速度更快。
All the other specs look good. Perhaps Java doesn't detect the 9600GS and doesn't use hardware acceleration, but I doubt this.
所有其他规格看起来都不错。也许 Java 没有检测到 9600GS 并且没有使用硬件加速,但我对此表示怀疑。
Also check the OS configuration. On Windows, you can turn off hardware acceleration for debugging purposes.
还要检查操作系统配置。在 Windows 上,您可以关闭硬件加速以进行调试。
Of course the best way to handle this would be to change your code - resize the image or split it up into chunks as DNS proposed. You'll never be able to see the whole image as it is on the screen.
当然,处理此问题的最佳方法是更改您的代码 - 调整图像大小或按照 DNS 建议将其拆分为多个块。您永远无法看到屏幕上的整个图像。
回答by DNS
How are you judging the computers' power? A 50x25 K 32-bit image takes more than 4.5 GB RAM to hold in memory (50000 * 25000 * 4 bytes). If one computer has more RAM than another, that can make a huge difference in speed, because it won't have to swap to disk as often. You should consider grabbing subsections of the image and working with those, instead of the whole thing.
你如何判断计算机的能力?50x25 K 32 位图像需要超过 4.5 GB RAM 才能保存在内存中(50000 * 25000 * 4 字节)。如果一台计算机的 RAM 多于另一台计算机,则速度可能会有很大差异,因为它不必经常交换到磁盘。您应该考虑抓取图像的子部分并使用它们,而不是整个图像。
Edit: Are you using the latest Java & graphics drivers? If your image is only 5Kx2.5K, the only thing I can think of is that it's doing it without any hardware acceleration.
编辑:您使用的是最新的 Java 和图形驱动程序吗?如果你的图像只有 5Kx2.5K,我唯一能想到的就是它没有任何硬件加速。
回答by Thorbj?rn Ravn Andersen
Check the screen settings. My bet is that pixel depth is different on the two systems, and that the slow one has an odd pixel depth related to the image object you are trying to display.
检查屏幕设置。我敢打赌,这两个系统上的像素深度是不同的,而较慢的系统具有与您尝试显示的图像对象相关的奇数像素深度。
回答by Ian Kemp
Since Java uses OpenGL to do 2D drawing, the performance of your app will be affected by the OpenGL performance of the graphics chip in the respective computer. Support for OpenGL is dwindling in the 3D industry, which means that (ironically) newer chips may be slower at OpenGL rendering than older ones - not only due to hardware but also drivers.
由于 Java使用 OpenGL 进行 2D 绘图,因此您的应用程序的性能会受到相应计算机中图形芯片的 OpenGL 性能的影响。3D 行业对 OpenGL 的支持正在减少,这意味着(具有讽刺意味的是)新芯片在 OpenGL 渲染方面可能比旧芯片慢——不仅是因为硬件,还因为驱动程序。
回答by lasantha
Have you tried Full-Screen Exclusive Mode?
您是否尝试过全屏独占模式?
This might help: http://download.oracle.com/javase/tutorial/extra/fullscreen/index.html
这可能会有所帮助:http: //download.oracle.com/javase/tutorial/extra/fullscreen/index.html

