7

我想使用处理在服务器端呈现可视化(无头,没有 GUI)。处理草图是静态的(即没有动画),所以我只需要抓取第一帧,我想将这个结果按需提供给我们的 Web 应用程序的用户。

我在 processing.org 论坛上搜索了一下,有人建议 Processing 不打算无头启动。我见过的唯一黑客行为是涉及启动无头 X11 显示器:

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

.. 这对我们不起作用,因为我们想要一个纯 Java 解决方案,并且不能总是保证在服务器端有一个 X 渲染器。

我如何在纯 Java 中做到这一点?

4

3 回答 3

1

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

编辑:这是从这里提取的引导命令行示例:

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
于 2010-06-22T14:23:12.750 回答
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");
于 2011-05-11T19:43:44.527 回答
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调用它的parent(the PApplet) 来获取一些帮助方法。但是,这还没有设置,因为我们一开始就不允许创建一个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()的代码副本。相反,两者都重定向到第三种方法,该方法将缺少的辅助方法重新实现为.PGraphicsgetFontMetrics(Font font)parent PAppletPAppletjava.awt.Component.getFontMetrics(Font font)

希望有帮助。

当明确调用文件作为绘图板时,拥有原生无头版本的处理会很好。

于 2014-10-15T13:25:40.803 回答