PNGファイルに処理スケッチを保存し、GUI/ディスプレイなしでサーバー側に保存します
-
29-09-2019 - |
質問
処理を使用してサーバー側の視覚化をレンダリングしたいと思います(重く、 GUIはありません)。処理スケッチは静的です(つまり、アニメーション化しません)ので、最初のフレームをつかむだけで、この結果をWebアプリケーションのユーザーにオンデマンドに提供したいと思います。
Processing.orgフォーラムで少し検索しましたが、処理は主に起動することを意図していないことが示唆されています。私がそれを行うことを見た唯一のハックは、ヘッドレスX11ディスプレイの起動を含むものです。
Xvfb :2 &
export DISPLAY=":2"
./myapp
killall -9 Xvfb
..純粋なジャバソリューションを持ちたいので、サーバー側のXレンダラーを常に保証することはできないため、私たちのために機能しません。
Pure Javaでこれを行うにはどうすればよいですか?
解決
XVFBはJavaレンダラーよりも高速である可能性が高く、ハードウェアでアクセラレーションされたXサーバーは大きなマージンで最速になりますが、「純粋な」Javaソリューションが必要な場合は、 純粋なJava AWTツールキット.
編集:ここにブートコマンドラインの例があります。 ここ:
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)、その上ですべての描画操作を実行します。次に、pgraphicsオブジェクトを.save()を使用して画像ファイルとしてディスクに保存します。
1これをパップレットから取得する必要があるかもしれませんが、直接作成できるかどうかはわかりません。
コードはモード以下に見えます。
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
.
したがって、そもそもパップレットオブジェクトを作成する方法はありません。
代わりに、あなたを作成します 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
( 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()
コードのコピーです PGraphics
呼び出されないことの変更とともに getFontMetrics(Font font)
存在しないものから parent
PApplet
. 。代わりに、欠落しているヘルパー方法を再配置する3番目の方法にリダイレクトします PApplet
のわずかに短いバージョンとして java.awt.Component.getFontMetrics(Font font)
.
それが役立つことを願っています。
描画ボードとしてファイルを明示的に呼び出すとき、処理のネイティブヘッドレスバージョンを持っているといいでしょう。