首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java中显示数百万张图片的最佳方式是什么?

在Java中显示数百万张图片的最佳方式是什么?
EN

Stack Overflow用户
提问于 2013-01-23 04:48:08
回答 2查看 9.1K关注 0票数 23

你看到了吗?

每座房子的每一块砖都是一幅16x16像素的图像。

你在这里看到的是一个基于简单JavaFX的版本,在X和Y上移动了一些Imageview,以提供“构造”的效果。

我只是使用paintComponent将其改写为Swing

问题:-使用JavaFX:我的电脑有问题。你在图片上看到的花了2秒加载,然后它移动得非常慢和颠簸。-使用Swing:我不知道如何根据亮度、阴影等调整每个块。所以看起来是这样的:

我应该选择什么方法?两者都有很大的缺点。我希望保留JavaFX方法,但也希望找到除Imageview之外的其他方法。这不应该是一个好主意。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-23 06:22:54

有关Swing优化和实现的信息,请参阅其他答案,因为我的答案是特定于JavaFX的。

如果您坚持使用JavaFX实现,这里有几个可以尝试的东西:

  1. 使用node.setCache(true)开启节点缓存,
  2. 使用node.setCacheHint(CacheHint.SPEED)启用高速节点缓存,一种是无效果的实现,另一种是有效果的实现,看看无效果的节点缓存效果是否明显更好。(如果是这种情况,你可能需要使用更有效的效果链,或者放弃一些altogether).
  3. Check Regions的效果,以确保你的设置在硬件/操作系统/驱动程序方面满足硬件加速的最低要求你使用的是css system和基于css的处理,注意css system不会引起太多开销(例如,通过使用不使用css的代码版本并比较它所需的css,实现一定程度的细节缩放,
  4. 确保您只加载一次给定的Image,并在多个ImageViews中重用它。对于测试cpu或显卡,请使用profiler进行识别,以查看它们是否为bottleneck.
  5. Try a Java 8 preview,它具有许多内部performance optimizations bottlenecks.
  6. Vary JavaFX。
  7. 如果您加载了大量图像,请使用background loading,并在加载图像时在前面播放动画或进度条。
  8. 如果您加载了大量图像,

scale them upfront in the Image constructor,这样它们就不会占用太多内存,也不会(潜在地)需要额外的处理能力来处理额外的像素(只有在使用大量不同的、非常高分辨率的纹理时才需要考虑--而你似乎并没有这么做)。

例如:

代码语言:javascript
复制
Image tile = new Image("tile.png");

Group house = new Group();
house.setCache(true);
house.setCacheHint(CacheHint.SPEED);

Effect lighting = new Lighting();

for (int i = 0; i < houseWidth; i++) {
  // here is the critical part => don't do new ImageView(new Image("tile.png"))
  ImageView tileView = new ImageView(tile));
  tileView.setEffect(lighting);
  tileView.setCache(true);
  tileView.setCacheHint(CacheHint.SPEED);

  house.add(tileView);  
}

Mantrid的建议很有趣。我相信,使用JavaFX,您不需要自己实现脏矩形算法(因为底层平台能够为您处理脏区域)。这可能是因为它是一种通用机制,它没有提供您的特定情况所需的优化级别,在这种情况下,您需要自己处理脏处理(例如,通过从场景图中删除节点并根据需要重新添加它们)。

此外,预先计算图像上的模糊/亮度等可以通过在JavaFX中定义效果,将效果应用于离屏ImageView节点,然后使用离屏ImageView节点的taking a snapshot来获得预先计算的图像。这项技术将允许您重用现有的JavaFX效果管道,而无需使用ConvolveOp机制重新实现它。也许您只需在ImageView节点上将cache设置为true并将cacheHint设置为speed,就可以获得相同的性能级别,因为我相信这在幕后会做类似的事情(即以增加内存使用量为代价来提高速度)。

JavaFX场景图非常高效,可以处理数以千计的节点。但是,您的应用程序中可能有更多的内容。如果上面的优化点对您没有帮助,那么您可能需要计算节点数,并将您的问题的引用(可能还有一些资源)发布到了解JavaFX应用程序优化细节的JavaFX开发人员所在的open-jfx mailing list

与JavaFX 2.2中的3D场景图相比,JavaFX 8对3D scenegraphs的支持要好得多。您当前的应用程序似乎是psuedo-3d,您可以变换2D对象,单独应用照明效果,并调整每个磁贴的亮度以获得3D外观。如果是这样的话,使用完全硬件加速的3D场景图和统一的3D照明模型可能最终会表现得更好,看起来更好,更容易使用-您必须在应用程序的上下文中对其进行评估,看看是否值得将您的应用程序从2D JavaFX场景图切换到3D JavaFX场景图,或者从JavaFX切换到Swing或其他一些技术,如libgdx

附录

Mizur的一些附加问题的答案:

那么,为什么它们如此耗电呢?

从我的回答中可以看出,性能有很多方面,所以找出一个特定的原因来解释为什么某些东西是耗电的,有时是困难的,而且通常是不可能的。有时,这是导致性能问题的各种因素的组合。最大的成功通常来自于优化在最内部循环中执行的东西,或者通过改变用于解决问题的策略。

如果他们需要这么多,请让我移动瓷砖,或请只是显示,不?

就仅为您移动的东西消耗资源而言,JavaFX场景图对此进行了一些优化,像cachehints这样的东西可以进一步提高性能。也许它们不足以满足您的特定用例或您使用系统的方式。您可能需要更改算法以减少系统负载。

有没有一种方法可以用Imageview技术生成每一座建筑的图像,然后将这些建筑图像整合到最终场景中?

可以-您可以使用多个图像和节点将建筑物渲染到屏幕外场景,使用snapshot the offscreen scene创建单个图像,然后将该图像叠加到最终场景上。

票数 41
EN

Stack Overflow用户

发布于 2013-01-23 05:10:42

在绘制图像之前修改图像上的模糊/亮度等

我自己还没有用过它,但是这里有一个提示-使用Swing/AWT Kernel+ConvolveOp机制:http://www.java-tips.org/java-se-tips/java.awt.image/styling-digital-images-with-convolveop.html

代码语言:javascript
复制
BufferedImage biSrc = ...
BufferedImage biDest = ...

float[] data = new float[] { 0.0625f, 0.125f, 0.0625f, 0.125f, 0.25f, 0.125f, 0.0625f, 0.125f, 0.0625f };
Kernel kernel = new Kernel(3, 3, data);
ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
convolve.filter(biSrc, biDest);

操作通过3x3矩阵(数据)定义。你可以搜索一下brigthness,blur等的例子。

图片加载花了2秒钟,但它的移动非常缓慢和抖动

使用脏矩形算法:Dirty Rectangles

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14467719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档