Guardar un boceto de procesamiento en un archivo PNG, del lado del servidor sin GUI / pantalla
-
29-09-2019 - |
Pregunta
Me gustaría usar procesamiento para representar una visualización en el lado del servidor (headlessly, con sin interfaz gráfica de usuario ). El procesamiento boceto es estática (es decir, no animado), por lo que sólo tendrá que tomar el primer fotograma, y ??me gustaría servir a este resultado a los usuarios de nuestra aplicación web bajo demanda.
he buscado todo un poco en los foros processing.org y se ha sugerido que el procesamiento no está destinado a ser lanzado headlessly. La única hackear he visto hacerlo es uno que involucró el lanzamiento de un display X11 sin cabeza:
Xvfb :2 &
export DISPLAY=":2"
./myapp
killall -9 Xvfb
.. Lo que no va a funcionar para nosotros, ya que nos gustaría tener una solución pura en Java y no siempre podemos garantizar un procesador de X en el lado del servidor.
¿Cómo puedo hacer esto en Java puro?
Solución
Xvfb es probable que sea más rápido que un procesador java, y un servidor de X acelerado por hardware será el más rápido por un amplio margen, pero si quieres una solución de Java 'puro' que podría probar el Pure Java AWT Toolkit
EDIT: He aquí un ejemplo de línea de comandos de arranque levantado de aquí :
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
Otros consejos
Crear una aplicación Java estándar sin cabeza, cree un objeto PGraphics en ella (1) y realizar todas sus operaciones de dibujo en eso. A continuación, guarde los PGraphics objeto en el disco como un archivo de imagen utilizando .save ().
1 Es posible que necesite para obtener esto de un PApplet, no estoy seguro de si se puede crear directamente.
El código será el modo o menos el siguiente aspecto:
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");
La solución de Ollie Glass dejó de trabajo porque el constructor de cheques PApplet/Applet
si el entorno es sin cabeza o no, es decir, -Djava.awt.headless=true
.
Así que no hay manera de crear un objeto PApplet en el primer lugar.
En su lugar, crear su PGraphics
directamente. Por ejemplo, para dibujar todo en un 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();
La adición de texto todavía producirá una excepción ya que el PGraphics
subyacente llama a su parent
(el PApplet
) para algunos métodos de ayuda. Sin embargo, esto no ha sido ajustada, porque no se nos permite crear un PApplet
en el primer lugar.
Una solución es deshacerse de estas llamadas a la función que está creando su propia versión de PGraphicsPDF
. Por ejemplo
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()
y textDescent()
son copias del código de PGraphics
con el cambio de no llamar la getFontMetrics(Font font)
from parent
PApplet
que no existe. En cambio, tanto redirección al tercer método que reimplementa el método de ayuda que falta de PApplet
como una versión ligeramente más corto de java.awt.Component.getFontMetrics(Font font)
.
Espero que ayude.
Sería bueno tener una versión nativa de procesar sin cabeza cuando se llama explícitamente a un archivo como tablero de dibujo.