繁体   English   中英

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

[英]Save a Processing sketch to a PNG file, server-side with no GUI/display

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

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

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

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

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

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

创建一个标准的无头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");

来自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)存在的parent PApplet调用getFontMetrics(Font font) 而是重定向到第三个方法,该方法重新实现了PApplet的缺失辅助方法,作为java.awt.Component.getFontMetrics(Font font)的略短版本。

希望有所帮助。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM