8

Me gustaría utilizar el procesamiento para representar una visualización en el servidor (sin cabeza, con sin interfaz gráfica de usuario). El boceto de Procesamiento es estático (es decir, no anima), por lo que solo necesito tomar el primer fotograma, y ​​me gustaría mostrar este resultado a los usuarios de nuestra aplicación web a pedido.Guardar un boceto de procesamiento en un archivo PNG, del lado del servidor sin interfaz gráfica de usuario/pantalla

He buscado un poco en los foros de processing.org y se ha sugerido que el procesamiento no está destinado a ser lanzado sin pena. El único truco que he visto hacerlo es uno que implica el lanzamiento de un display X11 sin cabeza:

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

.. Lo que no se va a trabajar para nosotros como nos gustaría tener una solución pura en Java y puede No siempre garantizamos un representador X en el lado del servidor.

¿Cómo hago esto en Java puro?

Respuesta

1

Xvfb es probable que sea más rápido que un renderizador Java, y un servidor X acelerado por hardware será el más rápido por un gran margen, pero si quieres una solución java 'pura' puedes probar el Pure Java AWT Toolkit.

EDIT: He aquí un ejemplo de línea de comandos de arranque levantado de here:

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 
+0

Este hilo de 3 años en processing.org dice que PJA no es compatible con el procesamiento: http://processing.org/discourse/yabb2/YaBB.pl?num=1193317878. ¿Alguna idea sobre si esto ha progresado? – Maciek

+0

Cuando he tenido este problema acabo poco la bala y se instala un servidor X. Este es el más rápido y más compatible, ¿y por qué hacer que la situación sea más difícil de lo que ya es? En mi compañía pasamos un año tratando de construir una solución 'java pura' que luego tiramos a la ventana ya que no podía tratar todas las cajas de esquina. Tienes que usar la herramienta adecuada para el trabajo. Te sugiero que vayas a X, xvfb si no tienes una tarjeta gráfica en la caja. –

+0

Xvfb estaría bien para nuestro servidor Linux, pero algunos de nuestros cuadros de desarrollo están basados ​​en Windows. ¿Es posible ejecutar Xvfb en Cygwin? – Maciek

1

Crear una sin cabeza aplicación Java estándar, cree un objeto PGraphics en ella (1) y realizar todas sus operaciones de dibujo en eso. A continuación, guarde el objeto PGraphics en el disco como un archivo de imagen usando .save().

1 Es posible que deba obtenerlo de un PApplet, no estoy seguro si puede crearlo directamente.

El código será el modo o menos este 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"); 
0

La solución de Ollie Glass dejó de funcionar porque el constructor de PApplet/Applet comprueba si el medio ambiente es sin cabeza o no, es decir -Djava.awt.headless=true.

Así que no hay forma de crear un objeto PApplet en primer lugar.

En su lugar, cree 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(); 

Añadir texto seguirá siendo una excepción ya que el PGraphics que subyace en sus llamadas parent (el PApplet) para algunos métodos de ayuda. Sin embargo, esto no se ha establecido porque, en primer lugar, no se nos permite crear un PApplet.

Una solución es deshacerse de estas llamadas de función 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 getFontMetrics(Font font) del parentPApplet que no existe. En su lugar, ambos redireccionan al tercer método que vuelve a implementar el método de ayuda faltante de PApplet como una versión ligeramente más corta de java.awt.Component.getFontMetrics(Font font).

Espero que ayude.

sería bueno tener una versión nativa de procesamiento sin cabeza cuando se llama explícitamente a un archivo como tablero de dibujo.

Cuestiones relacionadas