【发布时间】:2014-10-04 19:11:13
【问题描述】:
我正在使用在 Linux CentOS 上的 Tomcat 7 上运行的 servlet 中创建带有简单黑白线条图的小型 png 文件,并使用帧缓冲区 Xvfb 来提供图形资源。然后我的目标是在服务器返回的 html 页面上显示这个 png 文件。我发现偶尔(比如 10 张图片中的一张)显示为空白,有时甚至显示为半画。我检查了服务器上相应的 .png 文件,它们确实在这些情况下生成为空白或半画。
这就是我的代码的样子(更复杂的是,ChimePro 是专有类库的一部分,我没有它的代码;它只是扩展了 Panel 或 Canvas):
Frame f = new Frame();
ChimePro cp = new ChimePro();
f.add(cp);
f.addNotify();
cp.setBounds(0,0,200,200);
BufferedImage bi = new BufferedImage (200,200,BufferedImage.TYPE_BYTE_INDEXED);
Graphics g = bi.createGraphics()
cp.paint(g);
File ffjj = new File("file.png");
ImageIO.write(bi, "png", ffjj);
因此看起来好像paint(g) 或者可能不太可能的ImageIO.write() 方法没有像它们应该做的那样阻塞,并且即使尚未创建正确的文件,程序也会继续前进。 有趣的是,取决于我在 Tomcat 启动之前如何指向 DISPLAY 变量——无论是指向在同一服务器上模拟 X 环境的 Xvfb 屏幕,还是指向在远程机器上运行的一些真实 X 显示器——空白或损坏图片的概率会发生变化.
关于如何处理此问题以确保我的用户不会看到空白或损坏的图纸有什么想法吗? 我实际上是在写少量的短文件,所以这与速度无关,只是为了避免显示错误绘制的图片。 将不胜感激任何建议。
这是一个例外(仅在某些图纸中任意发生 - 不取决于图纸的内容,但可能取决于某些镀锡):
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerExceptio
at com.mdli.chime.ChimePro.paint(ChimePro.java)
at java.awt.Canvas.update(Canvas.java:142)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:255)
at sun.awt.X11.XRepaintArea.updateComponent(XRepaintArea.java:60)
at sun.awt.RepaintArea.paint(RepaintArea.java:232)
at sun.awt.X11.XComponentPeer.handleEvent(XComponentPeer.java:591)
at java.awt.Component.dispatchEventImpl(Component.java:4937)
【问题讨论】:
-
有很多事情可能会出错。如果框架没有实现(附加到本地对等点),它将无法正确绘制并导致错误。由于容器尚未经过验证(基本上已布局),因此它可能无法正确显示。您应该使用 printAll 而不是paint,因为 printAll 不是双缓冲的,除此之外。您还应该在尝试保存之前调用 g.dispose()。 ImageIO.read/write 也保证阻塞
-
您将花费大量精力来制作简单的黑白线条图。不需要frame或者panel,直接画到BufferedImage即可
-
我想我仍然需要 ChimePro 实例。我会尝试在没有框架的情况下做到这一点。但是即使没有 Frame,我仍然需要参考一些 X 窗口——比如 Xvfb,或者远程机器;对吗?
-
我不知道 ChimePro 在做什么。为了使用 printAll,您不需要将组件附加到本机对等节点,这是它的好处之一,但您需要确保组件具有大小并正确布局其内容...跨度>
-
所以使用 printAll 我不需要以任何形式或形式对 X11 进行任何引用吗?抱歉,我不太熟悉这个本地同行术语,所以我再次询问。
标签: java servlets png gif headless