渲染大图像时的javafx NullPointerException

时间:2014-05-05 08:11:25

标签: java image javafx

我尝试使用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)

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

我的猜测是图像尺寸太大而无法呈现,但我无法找到任何来源来验证这一点,也无法找到解决问题的任何内容。

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

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

3 个答案:

答案 0 :(得分:4)

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

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

-Dprism.order=j2d

-Dprism.order=sw

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

答案 1 :(得分:3)

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

-Dprism.order=sw
-Xmx1024m

我需要他们两个。

答案 2 :(得分:0)

我通过VM参数为我解决了这个问题:

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