当前位置: 首页 > 知识库问答 >
问题:

JavaFx与摇摆图像可视化

彭仲卿
2023-03-14

我正在研究将应用程序从Swing传递到JavaFX8是否合理,我需要帮助。该应用程序实时可视化图像,基本上我以一定的频率更新图像,例如1秒。图像的尺寸为28k x 4k;当我使用JavaFx imageView时,与Swing相比,性能很差。(fps较低,约为1-2,应用滞后)。我是这样做的:

    animation = new Timeline();
    animation.getKeyFrames().add(new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            for (int count = 0; count < 1; count++) {
                if (indicator)
                    imageView.setImage(writableImage);
                else
                    imageView.setImage(image1);
                indicator = !indicator;
            }
        }
    }));
    animation.setCycleCount(Animation.INDEFINITE);

所以我尝试使用JavaFx画布:

    imageCanvas.setHeight(image1.getHeight());
    imageCanvas.setWidth(image1.getWidth());
    imageCanvas.getGraphicsContext2D().drawImage(image1, 0, 0);

当我尝试它时,我得到以下错误。

java.lang.NullPointerException
    at com.sun.prism.impl.BaseGraphics.drawTexture(BaseGraphics.java:400)
    at com.sun.prism.impl.ps.BaseShaderGraphics.drawTexture(BaseShaderGraphics.java:139)
    at com.sun.javafx.sg.prism.NGCanvas.handleRenderOp(NGCanvas.java:1336)
    at com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:1086)
    at com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:595)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2067)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1959)
    at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
    at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2067)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1959)
    at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
    at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)
    at com.sun.javafx.sg.prism.NGNode.renderForClip(NGNode.java:2308)
    at com.sun.javafx.sg.prism.NGNode.renderRectClip(NGNode.java:2202)
    at com.sun.javafx.sg.prism.NGNode.renderClip(NGNode.java:2228)
    at com.sun.javafx.sg.prism.CacheFilter.impl_renderNodeToCache(CacheFilter.java:663)
    at com.sun.javafx.sg.prism.CacheFilter.render(CacheFilter.java:567)
    at com.sun.javafx.sg.prism.NGNode.renderCached(NGNode.java:2372)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2058)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1959)
    at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
    at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2067)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1959)
    at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
    at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2067)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1959)
    at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
    at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)
    at com.sun.javafx.sg.prism.NGNode.renderForClip(NGNode.java:2308)
    at com.sun.javafx.sg.prism.NGNode.renderRectClip(NGNode.java:2202)
    at com.sun.javafx.sg.prism.NGNode.renderClip(NGNode.java:2228)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2061)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1959)
    at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
    at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2067)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1959)
    at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
    at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:576)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2067)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1959)
    at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:474)
    at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:320)
    at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:91)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.lang.Thread.run(Thread.java:745)

这个问题是由图像的尺寸引起的,因为它适用于较小的图像。首先,我不明白为什么imageView的性能比Swing差那么多?(在swing中,我使用了一个扩展JPanel和paintComponent方法的面板。)

其次,JavaFx中画布的大小是否有某种限制?

提前谢谢你。

共有1个答案

淳于健
2023-03-14

为什么您的JavaFX应用程序不起作用

28k x 4k是一个绝对庞大的映像,JavaFX 8不直接支持硬件管道。我不知道这一限制是否在任何地方都有正式记录。

请参阅:JavaFX中画布的最大尺寸。

默认的JavaFX渲染管道将尝试将图像(和画布)绘制到视频卡上的纹理(用于硬件加速合成支持)。视频卡支持的纹理大小有限,通常是二次幂,例如8192 x 8192。JavaFX(至少在我之前使用过的版本中)如果试图渲染的图像大于底层视频硬件支持的最大纹理大小,则会抛出一个异常。

潜在的解决方法

要解决JavaFX中的纹理大小限制,请处理图像的传入数据,并将其加载到7个4k x 4k图像中(使用带像素写入器的可写图像)。执行此操作时,请确保输入数据以适当的像素格式编码,例如,ByTebGraphResistence,否则将需要进行数据转换,这可能会极大地影响应用程序的性能。

JavaFX有一些未记录的开关,用于禁用硬件渲染,而使用软件渲染管道。这些开关可能允许也可能不允许应用程序在不实现上述平铺算法的情况下处理大尺寸的图像,但是,它可能对整个应用程序更好,使硬件加速图形管道保持启用状态,并对应用程序进行编码,使其在该管道的限制范围内工作(通过实现用于大图像支持的自定义平铺算法)。

性能方面

至于JavaFX程序与Swing程序的性能差异,如果没有这两个程序的源代码,这是不可能分析的(即使提供了源代码,也可能很难分析)。因此,我不会对你问题的这一方面作进一步评论。

Canvas是一个比ImageView更复杂的控件,在这个任务中使用Canvas不太可能比使用ImageView提高性能。

 类似资料:
  • 例: “foo”和“bar”可以是任何字符串键,但它们在键集中应该是唯一的。 我知道,使用Swagger,我可以定义一个对象数组,但这给出了一个不同的API,因为那时我们将拥有如下内容: 我已经阅读了“开放API规范”-“添加地图数据类型支持#38”页面。据我了解,它推荐使用additionalProperties,但似乎并没有回答我的需求(或者说与我使用的Swagger UI 2.1.4不兼容)

  • 我的一个项目是使用Apache Wicket 6.x,我有一些使用三柱门Rest的API(资源),它正在完美地工作。 但是对于我的API文档,我正在为这些API维护一个谷歌文档。问题是,每当任何API甚至新API上发生更改时...我需要更新此 API 文档。本文档很可能未更新。 在我的其他Spring靴项目中,我使用的是 swagger,API 文档可以通过 swagger-ui 查看。 我想知道

  • 基本上,我有一个方法可以将Image从数据库加载到ImageView中,还有第二个方法可以更改图像,我成功地运行了这两个方法,没有出现异常,但是在change eImage()方法中的setImage之后,我需要更新什么以及如何(场景、阶段)是可能的。我知道在javafx中没有像swings中的repaint()这样的方法,那么我该如何处理呢?

  • 问题内容: 我一直在使用一个简单的动画上。但是,当观看动画时,我会遇到难以置信的震荡。我应该采取什么步骤来优化此代码? 不知道这是否重要,但是我正在使用OpenJDK 1.8.0_121版本。 任何帮助表示赞赏。 问题答案: 在与Yago进行了精彩的讨论之后,我发现问题围绕多个领域展开,很大程度上归因于Java将更新与操作系统和硬件同步的能力,有些是您可以控制的,有些是无法控制的。 受到Yago的

  • 嗯,这是一个非常新的提示。我声明要在window builder的帮助下自己编写GUI应用程序的代码,我已经决定停止使用netbeans,因为我在这里读到一些人说这很好。你可能认为我没有调查,但相信我,我做了功课。。。 我尝试了甲骨文所说的方式: > 公共类MyClass实现ActionListener{ someComponent。addActionListener(instanceOfMyCl

  • 我有一个java项目(tomcat webapp)和一些REST Api。我想为他们生成大摇大摆的文档。我从本教程(github)开始。我没有maven我们使用蚂蚁任务。我加入了swagger-annotations-1.5.0。jar和所有随swagger jaxrs jar 1.5.0版本附带的jar(如果有用的话,我可以包括一个完整的列表),我已经注释了一些方法,我有一个如下的配置类: }