将处理草图保存到服务器端的PNG文件,没有GUI /显示

时间:2010-06-22 14:09:03

标签: java image-processing server-side processing data-visualization

我想使用Processing在服务器端渲染可视化(无头,无GUI )。处理草图是静态的(即没有动画),因此我只需要抓住第一帧,并且我希望按需将这个结果提供给我们的Web应用程序的用户。

我在processing.org论坛上进行了一些搜索,并且有人建议Processing不会无头启动。我见过的唯一一个黑客是推出一个无头X11显示器:

Xvfb :2 &
export DISPLAY=":2"
./myapp
killall -9 Xvfb

..这对我们不起作用,因为我们希望有一个纯Java解决方案,并且无法始终保证服务器端的X渲染器。

如何在纯Java中执行此操作?

3 个答案:

答案 0 :(得分:1)

Xvfb可能比java渲染器更快,硬件加速的X服务器将是最快的,但如果你想要一个'纯'java解决方案,你可以尝试Pure Java AWT Toolkit

编辑:这是从here取消的启动命令行示例:

java -Xbootclasspath:JDK/jre/lib/rt.jar:LIB/pja.jar -Dawt.toolkit=com.eteks.awt.PJAToolkit -Djava.awt.graphicsenv=com.eteks.java2d.PJAGraphicsEnvironment -Djava.awt.fonts=JDK/jre/lib/fonts mainclassname args

答案 1 :(得分:1)

创建一个标准的无头Java应用程序,在其中创建一个PGraphics对象(1)并对其执行所有绘图操作。然后使用.save()将PGraphics对象作为图像文件保存到磁盘。

1您可能需要从PApplet获取此信息,我不确定您是否可以直接创建它。

代码看起来像这样的模式:

PApplet applet = new PApplet();
PGraphics g = applet.createGraphics(200, 400, PApplet.JAVA2D) // same params as size()
g.beginDraw();
g.ellipse // ... etc, your drawing goes here
g.endDraw();
g.save("filename.png");

答案 2 :(得分:0)

Ollie Glass的解决方案停止工作,因为PApplet/Applet的构造函数检查环境是否无头,即-Djava.awt.headless=true

因此,首先无法创建PApplet对象。

而是直接创建PGraphics。例如,将所有内容绘制成pdf

PGraphics pdf = new PGraphicsPDF();
pdf.setPrimary(false);
pdf.setPath(filename);
pdf.setSize(sizeX, sizeY);
// pdf.setParent(new PApplet()); This is intentionally NOT called.

pdf.beginDraw();

// draw everything

pdf.dispose();
pdf.endDraw();

添加文本仍然会引发异常,因为基础PGraphics会调用其parentPApplet)来获取某些辅助方法。但是,尚未设置此项,因为我们不允许首先创建PApplet

解决方法是摆脱这些函数调用创建自己的PGraphicsPDF版本。例如

class MyPGraphicsPDF extends PGraphicsPDF{

    @Override
    public float textAscent() {
        if (textFont == null) {
          defaultFontOrDeath("textAscent");
        }

        Font font = (Font) textFont.getNative();
        //if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
        if (font != null) {
          FontMetrics metrics = this.getFontMetrics(font);
          return metrics.getAscent();
        }
        return super.textAscent();
      }

    @Override
      public float textDescent() {
        if (textFont == null) {
          defaultFontOrDeath("textDescent");
        }
        Font font = (Font) textFont.getNative();
        //if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
        if (font != null) {
          FontMetrics metrics = this.getFontMetrics(font);
          return metrics.getDescent();
        }
        return super.textDescent();
      }

    public FontMetrics getFontMetrics(Font font) {
        FontManager fm = FontManagerFactory.getInstance();
        return sun.font.FontDesignMetrics.getMetrics(font);
    }
}

textAscent()textDescent()是来自PGraphics的代码的副本,但未调用getFontMetrics(Font font)的{​​{1}}更改为parent PApplet }。相反,两者都重定向到第三个方法,该方法重新实现PApplet的缺失辅助方法,作为java.awt.Component.getFontMetrics(Font font)的略短版本。

希望有所帮助。

当明确地要求将文件作为绘图板时,有一个原生的无头版处理会很好。