我的应用程序,使用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)
它同样是一个没有调用的线程触及我的代码。
答案 0 :(得分:0)
它也发生在我身上......
如果快照最终变大,就会发生这种情况。
我能够通过在SnapshotParameters
中添加一个比例来解决这个问题。一旦将手放在图像上,就可以做任何你想做的事情,包括恢复尺寸。
答案 1 :(得分:0)
TL; DR:
function theYears() {
"use strict";
var firstInput = parseInt(document.getElementById("firstInput").value),
secondInput = parseInt(secondInput = document.getElementById("secondInput").value),
myDiv = '',
myResult = document.getElementById("result");
var years;
myDiv = "<select>";
for (years = firstInput; years <= secondInput; years += 1) {
myDiv += '<option>' + years + '</option>';
}
myDiv += "</select>";
myResult.innerHTML = myDiv;
}
检查您的最大vram限制并查看您实际消耗了多少vram <input type="text" id="firstInput">
<input type="text" id="secondInput">
<input type="button" id="excute" value="Enter" onclick="theYears();">
<div id="result"></div>
设置为较低的值可能有助于重现该问题-Dprism.poolstats=true -Dprism.verbose=true
设置为更高的值可能有助于解决问题我的案子(针对任何有兴趣的人)
如上面链接中所建议,我使用了-Dprism.maxvram=xxxxM
,发现maxvram足够高。无论如何,可以肯定的是,我添加了-Dprism.maxvram=xxxxM
,但没有帮助。有足够的内存,但分配失败,并出现以下错误:
-Dprism.poolstats=true -Dprism.verbose=true
很明显,即使限制足够高,JVM也无法分配足够的内存。搜索-Dprism.maxvram=1024M -Dprism.targetvram=512M
发现这实际上是Windows错误(https://docs.microsoft.com/en-us/windows/desktop/seccrypto/common-hresult-values):
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%)
最后,在检查了设备管理器之后,事实证明客户端已安装了新的图形卡,并且Windows Update更新了驱动程序。
答案 2 :(得分:0)
尝试从大节点制作快照时遇到了相同的问题。 就我而言,缩放是不可能的,因为我需要高分辨率的图像。 为了解决该问题,我从节点的各个子节制作了多个快照,然后将它们快照在一起。
这是我写的函数:
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();
}
}