呈现大图时的javafx NullPointerException

我正在尝试使用JavaFX 8下的GraphicsContext.drawImage(...)方法渲染.png图像。我的代码可以很好地处理大小为~1000px x 2000px的图像。 但不幸的是,我需要渲染大小为7000px x 14000px的图像。 加载此图像也可以正常工作,但是当调用drawImage(image, 0, 0, canvas.getWidth(), canvas.getHeight())方法时,我得到以下错误输出:

 java.lang.NullPointerException at com.sun.prism.impl.BaseGraphics.drawTexture(BaseGraphics.java:389) at com.sun.prism.impl.ps.BaseShaderGraphics.drawTexture(BaseShaderGraphics.java:139) at com.sun.javafx.sg.prism.NGCanvas.handleRenderOp(NGCanvas.java:1228) at com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:997) at com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:578) ... more rendering stuff here at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2043) at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1951) at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:469) at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:317) at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:89) 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:129) at java.lang.Thread.run(Thread.java:745) 

如果我在绘制到canvas时尝试调整图像大小或者尝试渲染整个图像时,它没有任何区别。

我的猜测是图像大小太大而无法呈现,但我无法找到任何来源来validation这一点,我也找不到任何解决我问题的方法。

我还对Java堆(使用Eclipse Memory Analyzer)进行了分析,结果显示图像大小约为376 MB。

基本上我的问题是:1。为什么我的程序崩溃了? 是因为图像太大了吗? 2.如果我的图像太大,我怎样才能增加Java的可用空间? 我的机器有8GB内存,显卡有1GB内存,所以<400MB的图像应该不是问题。

正如有人在评论中指出的那样 – 只有4k / 8k纹理才能适合你。 这是因为JavaFX可能使用GPU来渲染图像。 纹理大小限制可能是无法处理更大纹理的GPU或GPU驱动程序的限制。 它不能创建如此大的纹理,因此它返回null(这解释了NullPointerException)。

修复它的唯一方法是避免使用如此大的纹理或获得更好的硬件来支持更大的纹理。 使用软件渲染(可能非常慢)可以通过使用以下参数运行java来修复它:

 -Dprism.order=j2d 

要么

 -Dprism.order=sw 

但我不确定这是你想要达到的目标。

我可以用2个VM-Arguments来解决它:

 -Dprism.order=sw -Xmx1024m 

我需要他们两个。

我用VM-Arguments为我解决了这个问题:

-Dprism.poolstats=true -Dprism.maxvram=500m -Dprism.order=sw -Djavafx.animation.fullspeed=true