Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java显示数百万图像的最佳方式是什么?_Java_Swing_Imageview_Javafx - Fatal编程技术网

用Java显示数百万图像的最佳方式是什么?

用Java显示数百万图像的最佳方式是什么?,java,swing,imageview,javafx,Java,Swing,Imageview,Javafx,你看到了吗 每栋房子的每一块砖都是16x16像素的图像 在这里,您可以看到一个基于简单JavaFX的版本,其中一些Imageview在X和Y上移动,以产生“构造”的效果 我只是使用paintComponent将其调整为Swing 问题是: -使用JavaFX:我的计算机有问题。你在图片上看到的东西需要2秒钟才能加载,然后它移动得非常缓慢和急促。 -使用Swing:我不知道如何根据亮度、阴影等调整每个块。。看起来是这样的: 我应该选择什么方法?两者都有很大的缺点。我本来希望保留JavaFX方法

你看到了吗

每栋房子的每一块砖都是16x16像素的图像

在这里,您可以看到一个基于简单JavaFX的版本,其中一些
Imageview
在X和Y上移动,以产生“构造”的效果

我只是使用
paintComponent
将其调整为
Swing

问题是: -使用JavaFX:我的计算机有问题。你在图片上看到的东西需要2秒钟才能加载,然后它移动得非常缓慢和急促。 -使用
Swing
:我不知道如何根据亮度、阴影等调整每个块。。看起来是这样的:

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

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

我自己没有使用过它,但这里有一个提示-使用Swing/AWT内核+卷积机制:

通过3x3矩阵(数据)定义操作。您可以搜索亮度、模糊等示例

图片加载花了2秒钟,但在加载后移动非常缓慢和急促


使用脏矩形算法:

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

如果您坚持使用JavaFX实现,以下是一些可以尝试的方法:

  • 用于打开节点缓存
  • 用于启用高速节点变换
  • 提供一个没有效果的实现和另一个有效果的实现,看看没有效果的实现是否表现得更好。(如果是这种情况,您可能需要使用更有效的效果链或完全放弃某些效果)
  • 检查以确保您的设置在硬件/操作系统/驱动程序组合方面满足硬件加速的最低要求
  • 如果您正在使用和基于css的处理,请小心不要造成太多的开销(例如,使用不使用css的代码版本并比较其性能)
  • 如果需要,实施细节级别缩放(例如,缩小时为整个房屋提供单个图像,而不是为每个房屋瓷砖提供单独的图像)
  • 确保只加载给定的一次,并多次重复使用它
  • 使用探查器识别瓶颈
  • 改变测试cpu或图形卡,看看它们是否是瓶颈
  • 尝试一个,它为JavaFX提供了许多内部特性
  • 如果要加载大量图像,请在加载图像时使用并在前面播放动画或进度条
  • 如果你正在加载大量的图像,这样它们就不会占用太多的内存,或者需要(潜在的)额外的像素处理能力(只有当你使用很多不同的非常高分辨率的纹理时才需要考虑,而你似乎没有这样做)
  • 例如:

    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);  
    }
    
    Image tile=新图像(“tile.png”);
    组屋=新组();
    setCache(真);
    house.setCacheHint(CacheHint.SPEED);
    效果照明=新照明();
    for(int i=0;i不要新建ImageView(新建图像(“tile.png”))
    ImageView tileView=新的ImageView(平铺));
    tileView.setEffect(灯光);
    tileView.setCache(true);
    tileView.setCacheHint(CacheHint.SPEED);
    添加(tileView);
    }
    

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

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


    JavaFX场景图非常高效,可以处理数千个节点。但是,您的应用程序中可能有更多内容。如果上述优化点对您没有帮助,您可能需要计算节点数,并将您的问题(可能还有一些来源)的参考发布到了解JavaFX应用程序优化细节的JavaFX开发人员所在的位置

    JavaFX8对in的支持比JavaFX2.2中的3D场景图(大部分是无用的)要好得多。您当前的应用程序似乎是psuedo-3d,您可以在其中变换2D对象、单独应用照明效果并调整每个瓷砖的亮度以获得3d外观。如果是这样的话,使用具有统一3D照明模型的全硬件加速3D scenegraph可能最终表现更好,外观更好,更易于使用-您必须在应用程序的上下文中对其进行评估,以确定是否值得将应用程序从2D JavaFX场景切换到3D JavaFX场景,或从JavaFX切换到Swing或其他类似技术

    附录

    对Mizur的一些附加问题的回答:

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

    从我的回答中可以看出,有许多方面会影响性能,因此,请选择
    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);  
    }