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

如何解决无法识别的图像加载器:JavaFX中的null?

叶煌
2023-03-14

我的应用程序是使用JavaFX用Java 8编写的,它拍摄了屏幕截图,或者更确切地说是快照,并且两次生成了这个错误:

java.lang.IllegalArgumentException: Unrecognized image loader: null
    at javafx.scene.image.WritableImage.loadTkImage(WritableImage.java:240)
    at javafx.scene.image.WritableImage.access$000(WritableImage.java:46)
    at javafx.scene.image.WritableImage$1.loadTkImage(WritableImage.java:51)
    at javafx.scene.Scene.doSnapshot(Scene.java:1236)
    at javafx.scene.Node.doSnapshot(Node.java:1864)
    at javafx.scene.Node.snapshot(Node.java:1942)

到目前为止,在我的应用程序中,我无法复制它。搜索此问题时,我发现:

https://bugs.openjdk.java.net/browse/JDK-8116783

这表明:

https://bugs.openjdk.java.net/browse/JDK-8088198

这似乎是JavaFX中的一个公开错误:“如果维度大于最大纹理大小,则从快照引发异常”。

错误的描述说它偶尔会发生。有人知道捕获异常并重试是一种好方法还是解决方法吗?

更新:当我试图通过使屏幕截图非常大来重现这个错误时,我得到了一个完全不同的错误:

java.lang.NullPointerException
    at com.sun.prism.impl.ps.BaseShaderContext.initLCDBuffer(BaseShaderContext.java:703)
    at com.sun.prism.impl.ps.BaseShaderContext.validateLCDBuffer(BaseShaderContext.java:725)
    at com.sun.prism.impl.ps.BaseShaderGraphics.initLCDSampleRT(BaseShaderGraphics.java:1925)
    at com.sun.prism.impl.ps.BaseShaderGraphics.drawString(BaseShaderGraphics.java:2059)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$10.doPaint(WCGraphicsPrismContext.java:936)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(WCGraphicsPrismContext.java:1500)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(WCGraphicsPrismContext.java:1485)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext.drawString(WCGraphicsPrismContext.java:948)
    at com.sun.webkit.graphics.GraphicsDecoder.decode(GraphicsDecoder.java:299)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:92)
    at com.sun.webkit.WebPage.paint2GC(WebPage.java:734)
    at com.sun.webkit.WebPage.paint(WebPage.java:701)
    at com.sun.javafx.sg.prism.web.NGWebView.renderContent(NGWebView.java:96)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
    at com.sun.javafx.tk.quantum.QuantumToolkit$5.draw(QuantumToolkit.java:1393)
    at com.sun.javafx.tk.quantum.QuantumToolkit$5.run(QuantumToolkit.java:1429)
    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:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.lang.Thread.run(Thread.java:748)

它同样是一个线程,没有任何调用涉及我的代码。

共有3个答案

凌嘉勋
2023-03-14

我在尝试从大型节点创建快照时遇到了相同的问题。在我的情况下,缩放是不可能的,因为我需要一个高分辨率的图像。为了解决这个问题,我从节点的子部分创建了多个快照,然后将它们粘在一起。

这是我写的函数:

private void exportPng(final Node node, final String filePath) {

    final int w = (int) node.getLayoutBounds().getWidth();
    final int h = (int) node.getLayoutBounds().getHeight();
    final WritableImage full = new WritableImage(w, h);

    // defines the number of tiles to export (use higher value for bigger resolution)
    final int size = 2; 
    final int tileWidth = w / size;
    final int tileHeight = h / size;

    System.out.println("Exporting node (building " + (size * size) + " tiles)");

    try {
        for (int col = 0; col < size; ++col) {
            for (int row = 0; row < size; ++row) {

                final int x = row * tileWidth;
                final int y = col * tileHeight;
                final SnapshotParameters params = new SnapshotParameters();
                params.setViewport(new Rectangle2D(x, y, tileWidth, tileHeight));   

                final CompletableFuture<Image> future = new CompletableFuture<>();

                // keeps fx application thread unblocked
                Platform.runLater(() -> future.complete(node.snapshot(params, null)));
                full.getPixelWriter().setPixels(x, y, tileWidth, tileHeight, future.get().getPixelReader(), 0, 0);
            }
        }

        System.out.println("Exporting node (saving to file)");

        ImageIO.write(SwingFXUtils.fromFXImage(full, null), "png", new File(filePath));

        System.out.println("Exporting node (finished)");

    } catch (Exception e) {
        e.printStackTrace();
    }
}
谭修然
2023-03-14

太长别读:

  • 即使使用Oracle JVM,请参阅:https://wiki.openjdk.java.net/pages/viewpage.action?pageId=20415996

我的案子(对任何感兴趣的人)

正如上面链接中所建议的那样,我使用了Dprism。poolstats=真-朝鲜主义。verbose=true,并发现maxvram足够高。无论如何,可以肯定的是,我添加了朝鲜主义。maxvram=1024M-Dprism。targetvram=512M,但没有帮助。内存足够,但分配一直失败,出现以下错误:

D3D Vram Pool: 66.929.834 used (12,5%), 81.273.002 target (15,1%), 536.870.912 max
36 total resources being managed
average resource age is 12,6 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (13,9%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
31 resources contain interesting data (86,1%)
0 resources disappeared (0,0%)

Growing pool D3D Vram Pool target to 116.658.814
Growing pool D3D Vram Pool target to 131.338.878
Growing pool D3D Vram Pool target to 159.043.730
D3D hresult failed :D3D_ERROR ffffffff8007000e
java.lang.Exception: Stack trace
        at com.sun.prism.d3d.D3DContext.validate(D3DContext.java:133)
        at com.sun.prism.d3d.D3DContext.validatePresent(D3DContext.java:183)
        at com.sun.prism.d3d.D3DRTTexture.readPixels(D3DRTTexture.java:116)
        at com.sun.prism.d3d.D3DRTTexture.readPixels(D3DRTTexture.java:90)
        at com.sun.javafx.tk.quantum.QuantumToolkit$5.run(QuantumToolkit.java:1437)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
        at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
        at java.lang.Thread.run(Unknown Source)
D3D Vram Pool: 109.314.750 used (20,4%), 159.043.730 target (29,6%), 536.870.912 max
37 total resources being managed
average resource age is 13,1 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (13,5%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
32 resources contain interesting data (86,5%)
0 resources disappeared (0,0%)

2018-07-17 18:05:09 [JavaFX Application Thread] de.apris3.client.ErrorHandler.handle()
   ERROR: : java.lang.IllegalArgumentException: Unrecognized image loader: null
        at javafx.scene.image.WritableImage.loadTkImage(WritableImage.java:240)
        at javafx.scene.image.WritableImage.access$000(WritableImage.java:46)
        at javafx.scene.image.WritableImage$1.loadTkImage(WritableImage.java:51)
        at javafx.scene.Scene.doSnapshot(Scene.java:1236)
        at javafx.scene.Node.doSnapshot(Node.java:1864)
        at javafx.scene.Node.snapshot(Node.java:1942)
        ...
D3D Vram Pool: 112.230.142 used (20,9%), 159.043.730 target (29,6%), 536.870.912 max
40 total resources being managed
average resource age is 13,0 frames
0 resources at maximum supported age (0,0%)
5 resources marked permanent (12,5%)
0 resources have had mismatched locks (0,0%)
0 resources locked (0,0%)
35 resources contain interesting data (87,5%)
0 resources disappeared (0,0%)

显然,即使限制足够高,JVM也无法分配足够的内存。搜索D3D hresult失败:D3D_ERROR FFFFFFFF 8007000E显示它实际上是一个Windows错误(https://docs.microsoft.com/en-us/windows/desktop/seccrypto/common-hresult-values):

E_OUTOFMEMORY   Failed to allocate necessary memory     0x8007000E 
袁玮
2023-03-14

这也发生在我身上。。。

如果快照最终变得太大,就会发生这种情况。

我可以通过在SnapshotParameters添加一个比例来解决这个问题,比如一半。一旦你把手放在图像上,你就可以做任何你想做的事情,包括让它恢复大小。

 类似资料:
  • 问题内容: 我测试了此代码以创建带有图像的对话框。 我将图像文件放入目录中。但是由于某些原因,图像无法显示。你能帮我纠正我的错误吗? 问题答案: 只需替换以下代码: 有了这个 Docu参考。 https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html 当您将a传递给该类时,可以用 四种不同的方式 处理( 从do

  • 为了创建带有图像的对话框,我测试了这段代码。 我将图像文件放入目录。但是由于某种原因,图像不显示。你能帮我改正错误吗

  • 这是我的代码: controller.java main.java 当我运行我的项目并在文本字段中键入1并单击按钮时,它将显示图片。现在,在不关闭程序的情况下,我将一个2.png文件添加到res文件夹中。并在文本字段中键入2。点击该按钮后,它给我“java.lang.IllegalArgumentException:Invalid URL:Invalid URL或resource not Foun

  • 我对javafx非常陌生,而且已经学会了使用代码教程进行测试时: 异常是由第行

  • 我的JavaFX项目可以在一台机器中加载图像,但是相同的代码不能在另一台机器中加载图像。 我有包结构(在src中)-/com/mypackagestructure/view/images/,它保存图像文件。 我的CSS文件位于-/com/mypackagestructure/view/Login。css 我在另一台机器上有完全相同的代码(安装了相同的操作系统、相同的Eclipse IDE和JDK/

  • 我在从控制器加载javaFX中的图像时遇到了一些麻烦。 我把一些图像放在src/文件夹中,甚至放在img/文件夹中,但仍然得到“无效URL或未找到资源”。 但我无法检索图像“java.lang.IllegalArgumentException:无效URL或未找到资源” 谢谢你的帮助