Revision #1 Autor

Export aus ProcessingErgebnisse aus Processing für die Weiterverwendung ausgeben

Neben der Ausgabe von Screenshots und PDFs für die Weiterverwendung, bzw. in Adobe’s Photoshop(c) oder Illustrator(c) wird auch die Ausgabe von Text für das Speichern von Daten erläutert.

Es empfiehlt sich permantent den Entwicklungsstand von Projekten grafisch zu dokumentieren. Dabei geht es weniger um Veröffentlichungen — sondern um das Nachvollziehen des durchlaufenen Prozesses bei der Bearbeitung des Themas. Oft kommt es auf dem Weg zum Resultat zu interessanten Entdeckungen von grafischen Konstellationen aus älteren Abeitsständen, die wieder in den gegenwärtigen Stand übernommen werden.

Screenshot

Eine einfacher Extrakt des Zeichenflächeninhalts als Pixelgrafik ist die simpelste Form des Exports. Mittels eines Befehlaufrufs (save()) kann dies unter Angabe eines Dateinamens für das Zieldokument bwerkstelligt werden.
  • save() speichert den aktuellen Sketchfensterinhalt in eine Pixelgrafikdokument (jpeg, png, tiff oder targa). Als Parameter wird beim Aufruf der Dateiname des Bildes genannt. Wenn kein Dateitype angegeben ist, legt Processing das Bild automatisch als tiff ab. siehe Referenz
    save ("capture.png");
  • saveFrame() ermöglicht eine Serie von Screenshots zu speichern. Rauten dienen im Dateinamen als Platzhalten für die später von Processing eingesetzte Bildnummer. Dadurch kommt es nicht zum Überspeichern von existierenden Screenshots. siehe Referenz
    saveFrame ("capture-####.png");
Bsp.: Screenshot speichern
In diesem kleinen Beispiel wird auf Drücken der Taste 's' der save() Befehl zum Speichern des aktuellen Bildschirminhaltes aufgerufen. Ohne die Zeichenfläche zu leeren werden permanent rote Kreise platziert - die Anzahl der Elemente nimmt mit der Zeit zu. Es kommt zum Überschreiben des vorherigen Screenshots wenn 's' mehrmals während eines Programmablaufes betätigt wird (dieses Problem löst saveFrame()).
void setup () {
  size(320, 240);
  fill (255, 0, 0);
}

void draw () {
  ellipse (random (width), random (height), 10, 10);
}

void keyPressed () {
  if (key == 's') {
    save ("capture.png");
  }
}
Bsp.: Serie von Screenshots speichern
Basierend auf dem vorangegangenen Beispiel kommt es nun nicht mehr zum Überschreiben von existierenden Screenshots. Processing fügt für die Rauten (####) die aktuelle Bildnummer ein und verhindert damit Dopplungen von Dateinamen.
void setup () {
  size (320, 240);
  fill (255, 0, 0);
}

void draw () {
  ellipse (random (width), random (height), 10, 10);
}

void keyPressed () {
  if (key == 's') {
    saveFrame ("capture ####.png");
  }
}

PDF

Die Funktionalität PDF Dokumente aus Processing zu generieren gestattet sich bei dem Ausgabemedium vom Bildschirm zu lösen. Um hochauflösende, großformatige Drucke auf Grundlage von Vektorgrafiken in Processing zu zeichnen bedarf es nur weniger Schritte. Bei großen und rechenintensiven Projekten lohnt es sich auf die Ausgabe des Resultates im Sketchfenster zu verzichten. Processing erzeugt in diesem Fall nur die Pdf im Sketchordner und gibt keinerlei Rückmeldung. Ebenso ist das Betrachten der Pdf ausschlaggebend für Gestaltungsentscheidungen, wenn das Sketchfenster durch hohe Auflösung der Pdf nur einen Bruchteil der Arbeit abbildet. Die Basisumgebung von Processing umfasst die dafür benötigte Funktionalität nicht. Es bedarf des Einbezugs einer Erweiterung - sogenannten Bibliothek (engl. libraray). Die auf der Website runtergeladene Version des Programms bringt dies jedoch schon mit, muss von uns nur expliziet Angefordert werden. Dies geschieht durch den Aufruf von SketchImport Library...pdf in der Menüleiste von Processing. Am Kopf unseres Codebereichs erscheint nun folgende Zeile:
import processing.pdf.*;
Bedeutet: Processing holt sich damit die Werkzeuge um Pdf Dokumente im weiteren Verlauf erzeugen zu können.
  • beginRecord() erzeugt ein Pdf Dokument und startet die Aufnahme aller im Folgenden gezeichneten Elemente werden neben der Zeichenfläche auch im Pdf positioniert. siehe Referenz
    beginRecord (PDF, "my.pdf");
  • endRecord() beendet eine zuvor mit beginRecord() angefangene Aufnahme. siehe Referenz
    endRecord();
  • size() neben der Fenstergröße können bei diesem Befehl als dritten Parameter unterschiedliche Modi angegeben werden. Einer lautet PDF; Erstellung eines Pdf Dokuments im Sketchordner. Das Sketchfenster bleibt dabei geschlossen und alle Zeichenoperationen werden im Pdf ausgeführt. Als vierten Parameter muss ein Dateiname für das Dokument angegeben werden. siehe Referenz
    size (800, 600, PDF, "render.pdf");
Bsp.: Einzelbild (ohne Sketchfenster)
setup() um die Parameter PDF und den Dateinamen erweitert lässt das Sketchfenster geschlossen und zeichnet alle Elemente in eine Pdf. Da wir kein Feedback über den Stand des Programmablaufs erhalten, schließen wir die Applikation mit exit() am Ende des draw()-Blocks. [code| import processing.pdf.*; void setup() { size (320, 240, PDF, "vectors.pdf"); fill(255, 72, 0); } void draw() { ellipse (random (width), random(height), 80, 80); println ("done!"); exit(); } [/code]
Bsp.: Einzelbild (mit Sketchfenster)
Die Aufnahme startet mit beginRecord() im setup()-Block, außer der Fenstergröße entfallen weitere Parameter im size() Aufruf. Das Programm generiert ein einziges Bild, da in der ersten Zeile des draw()-Parts noLoop() die übliche Endlosschleife verhindert. Nach dem Zeichnen des Kreises wird die Aufnahme mit endRecord() beendet.
import processing.pdf.*;

void setup () {
  size (320, 240);
  beginRecord (PDF, "vectors.pdf");
  fill (255, 72, 0);
}

void draw () {
  noLoop();
  ellipse (random (width), random (height), 80, 80);
  endRecord ();
}
Bsp.: Bildserie (mit Sketchfenster)
Ohne noLoop() schreibt dieses Programm permanent in die im setup() angelegte PDF. Bei dem Drücken der Taste 'q' wird die Aufnahme beendet und das Fenster durch exit() geschlossen. Diese Struktur kann bei einer großen Anzahl an Zeichenoperationen pro Bild zum Überlaufen des Speichers führen, bzw. das Programm stürzt ab.
import processing.pdf.*;

void setup () {
  size (320, 240);
  beginRecord (PDF, "vectors.pdf");
  fill (255, 72, 0);
}

void draw () {
  ellipse (random (width), random (height), 20, 20);
}

void keyPressed () {
  if (key == 'q') {
    endRecord ();
    exit (); 
  }
}

Texte exportieren

Das Speichern von Textinhalten erlaubt Processing mit dem Befehl saveStrings(). Dafür wird eine Datei (UTF8 Format) Sketchordner angelegt, beachte das der Sketch dafür gespeichert sein muss.
  • saveStrings() speichert einen String-Array in eine Textdatei, relativ zum Sketchordner. Jedes Feld im String-Array entspricht einer Zeile im Textdokument. siehe Referenz
    String[] s = new String[2];
    s[0] = "Die Zeile #1";
    s[1] = "Die Zeile #2";
    saveStrings(s, "text.txt");
Bsp.: Text in Textdatei ablegen
Ohne jeglichen grafischen Output läuft dieses Programm ab. Einstellungen für das Sketchfenster nehmen wir nicht vor - der setup() Block bleibt leer. Zu Beginn des draw() Teils weisen wir Processing mit noLoop() an diesen einmalig auszuführen. Das Array aus Strings s dient zum Festlegen des späteren Inhalts im Textdokument. Die Anzahl der Felder im Array, in diesem Fall zwei, legt die Anzahl an Zeilen im Dokument fest. Das Feld mit dem Array-Index null repräsentiert die erste Zeile im Text, eins die Zweite etc. . Der Aufruf von saveStrings() führt das Anlegen der Textdatei durch. Wir übergeben lediglich den gewünschten Dateinamen und das String-Array welches abgelegt werden soll.
void setup () {
}

void draw () {
  // keine Endlosschleife, das 
  // Programm läuft einmal ab
  noLoop ();
  
  String[] s = new String[2];
  s[0] = "Dear sir or madam,"; // Zeile 1
  s[1] = "That's my small message."; // Zeile 2
  
  // Speichern im Dokument "text.txt"
  saveStrings ("text.txt", s);
  
  // Beenden des Programms
  exit ();
}
Bsp.: Text an Textdatei anhängen
Das vorherige Beispiel wir nun im ersten Teil ausgebaut. Wir erzeugen die Inhalte für das Textdokument nicht mehr statisch im Code, sondern laden diese aus einem bestehende Dokument mit dem Befehl loadStrings(). Das Resultat des Aufrufs wird in der Variable s1 abgelegt. Zum Problem wird nun die fixe Größe/Länge von Arrays. s1 ist ein Feld zu kurz, da jedes Feld eine Zeile im Textdokument darstellt. Deshalb initialisieren wir im nächsten Schritt ein weiteres String-Array mit dem Namen s2 und einer Länge von s1.length + 1. Unser Array s2, was zum Schluss im Textdokument landet, ist aber noch leer. Wir kopieren den ausgelesenen Inhalt aus s1 nach s2 mit einer for-Schleife und füllen das letzte Feld mit einer Zufallszahl. Das eigentliche Ablegen auf der Festplatte passiert wieder mit //saveStrings().
String document = "text.txt";

void setup () {
}

void draw () {
  // keine Endlosschleife, das 
  // Programm läuft einmal ab
  noLoop ();
  
  /* Inhalt des bestehenden Dokuments laden.
   * Dieser kommt in eine String-Array. Jede 
   * Zeile im Dokument ist ein Feld im Array.
   */
  String[] s1 = loadStrings (document);
  
  /* Erzeugen eines neuen, leeren String-Arrays.
   * Das besitzt ein Feld mehr als das Array
   * "s1", da es eine weitere Zeile speichern soll.
   */
  String[] s2 = new String[s1.length + 1];
  
  // Kopieren des Inhalts von "s1" nach "s2"
  for (int i=0; i < s1.length; i++) {
    s2[i] = s1[i];
  }
  
  // Inhalt für die weitere Zeile wird eine 
  // zufällige Zahl zwischen 0 und 50000
  s2[s2.length - 1] = "" + random (50000);
  
  // Speichern von "s2" im Dokument "text.txt"
  saveStrings ("text.txt", s2);
  
  // Beenden des Programms
  exit ();
}
Eine kleine Änderung um Textschnippsel an den Anfang von Dokumenten zu platzieren:
// Kopieren des Inhalts von "s1" nach "s2"
  for (int i=0; i < s1.length; i++) {
    s2[i+1] = s1[i];
  }
  
  // Inhalt für die weitere Zeile wird eine 
  // zufällige Zahl zwischen 0 und 50000
  s2[0] = random (50000);
s2[i+1] lässt das erste Feld im Array s2 leer. Dieses wird von uns im nächsten Schritt mit s2[0] = ... statisch mit dem neuen Inhalt befüllt.