绘制图像或绘制实心圆?
我们有一个旧的 Java Swing 应用程序。我们需要根据真实数据在画布上显示数千、数十万个小圆点。现在我们有一个小圆点的图像文件。当我们需要它时,我们会将该图像绘制到画布上数千次、数十万次。
现在我认为每次只绘制一个实心圆而不是加载图像并绘制它可能会更好(更好的性能和内存使用)。
你的意见怎么样?
谢谢,
We have an old Java Swing application. we need to display thousands, hundreds of thousands small circle spots on the canvas based on the real data. Right now we have an image file of a small circle spot. When we need it, we draw that image onto the canvas, thousands, hundreds of thousands times.
Now I am think it may be better (better performance and memory usage) to just draw a filled circle each time instead of load the image and draw it.
how about your opinion?
thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我现在不知道这是否有帮助,但您可以通过测试最坏的情况来测试哪一个适合您。但我认为实心圆圈是最好的。
I don't now if this would be helpful but you can test which one works for you by testing worst case . But I think filled circle would be best .
第三种方法是使用 unicode char 表示实心圆,●,因为您可以我敢打赌,渲染数千个字符(例如:一段文本)对于任何图形引擎来说都是最正常的事情。
A third way to do it is to use the unicode char for filled circle, ●, since you can bet that rendering thousands of chars (as in: a piece of text) is the most normal thing for any graphics engine.
很难预测哪个更快,因为某些情况下的某些操作是由显卡的 GPU 硬件加速的。
如果使用 GPU 来制作圆,那么这比 CPU 将缓冲圆的像素复制为图像要快得多。
还有 VolatileImage。也许可以使图像位块传送,从而最终加速它们。
找出答案的唯一方法是自己进行基准测试。
It's hard to predict which is faster, because certain operations under certain circumstances are accelerated by the GPU hardware of the video card.
If the GPU is used to make the circle, then that would be much faster than the cpu copying pixels of a buffered circle as an image.
There is VolatileImage as well. Perhaps it's possible to make the image blits so that they end up being accelerated.
The only way to find out is to benchmark it yourself.
您只需加载一次模板图像并将其保存在内存中,并根据需要使用 Graphics2D drawImage 函数将其复制到画布。由于调用 Flood-fill/扫描填充算法以及Bresenham 绘制圆圈。要优化渲染,您还可以抽取渲染结果或执行集群,因为无论如何,用户不会真正欣赏密集的重叠圆圈。
为了减少渲染调用,请测试模板所在的像素,如果它已经着色,则通过渲染。
这是一个很好的基准测试小程序。
You only need to load the template image once and hold it in memory and copy it to the canvas as needed using Graphics2D drawImage function. Drawing multiple filled circles may become expensive due to calls to the Flood-fill/Scan-fill algorithm as well as Bresenham to draw the circle. To optimize the rendering you can also decimate the rendered result or perform clustering, since the user will not really appreciate dense overlapping circles anyway.
To reduce render calls test the pixel where your template is going and pass a render if it is already coloured.
Here is a nice benchmarking applet.
几乎可以肯定,保存单个图像并多次绘制它比调用绘制实心圆要快得多。这是关于该主题的最新演示,表明绘制图像甚至比简单的水平十字还要快。 http://developers.sun .com/learning/javaoneonline/j1sessn.jsp?sessn=TS-4170&yr=2009&track=javase
It is almost certainly much faster to hold a single image and draw it many times than to make a call to draw a filled circle. Here is a recent presentation on the subject, showing that it is faster to draw an image than even a simple horizontal cross. http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-4170&yr=2009&track=javase
为代码计时
多次绘制图像肯定比多次绘制圆圈或字符串要快,而且很容易测试。在 PaintComponent() 方法的开头添加以下行:
如果时间始终为零,则可以改用 System.nanoTime()。
绘制到缓存图像
您可以做的另一件事是将这些圆圈绘制到图像上,并且仅在内容更改时重新创建图像。如果没有任何变化,只需将该图像绘制到 Graphics2D 对象上,而不是重新绘制所有圆圈。这通常称为双缓冲。您还可以使用易失性映像来利用硬件加速度。
创建兼容图像
您还应该通过使用 createCompatibleImage() 确保使用与用户显示器兼容的图像,如下所示:
更多提示
我推荐这本书< a href="http://filthyrichclients.org/" rel="nofollow">肮脏的富客户端。它有很多加快挥杆速度的好技巧。特别要注意第 4 章和第 5 章有关图像和性能的内容。
Time your code
It is most definitely faster to draw an image lots of times than drawing a circle or String lots of times and it's very easy to test. At the beginning of your paintComponent() method add the line:
If the times turn out to be zero all the time, you can instead use System.nanoTime().
Paint to Cached Image
Another thing you can do is to paint these circles onto an image and only recreate the image when the content changes. If nothing has changed just draw that image onto the Graphics2D object instead of redrawing all of the circles. This is commonly called double buffering. You also can use Volatile Images to take advantage of hardware acceleration.
Create Compatible Images
You should also make sure you use images that are compatible with the user's monitor by using createCompatibleImage() as shown below:
More Tips
I'd recommend the book Filthy Rich Clients. It has lots of great tips for speeding up swing. Especially look at chapters 4 and 5 about images and performance.