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.
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 ("capture.png");
saveFrame ("capture-####.png");
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"); } }
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"); } }
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 Vectorgrafiken 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 Sketch → Import 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 (PDF, "my.pdf");
endRecord();
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 Referenzsize (800, 600, PDF, "render.pdf");
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.
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 (); }
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 (); }
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 (); } }
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.
String[] s = new String[2]; s[0] = "Die Zeile #1"; s[1] = "Die Zeile #2"; saveStrings(s, "text.txt");
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 (); }
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.