簡體   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