Μια εισαγωγή στο περιβάλλον και τις δυνατότητες της γλώσσας Processing

dimitris | Σάβ, 12/15/2012 - 11:32 | 23'

Μαθαίνουμε να σχεδιάζουμε γραφικά και να δημιουργούμε αλληλεπιδράσεις με ελάχιστες γραμμές κώδικα, βασιζόμενοι στη γλώσσα προγραμματισμού Processing.

Του Γιώργου Χατζηκυριάκου *

Στα παραδείγματα που ακολουθούν, θα μελετήσουμε ορισμένες από τις εντολές της Processing που αφορούν το σχεδιασμό βασικών σχημάτων, σχεδιασμό κειμένου, την χρήση πληκτρολογίου/mouse μέσα στις εφαρμογές μας, καθώς επίσης το άνοιγμα, την επεξεργασία και την αποθήκευση μίας ψηφιακής εικόνας. Μπορείτε να κατεβάσετε όλο τον κώδικα του άρθρου από εδώ.

Τι είναι η Processing;

H Processing είναι μία ανοικτού κώδικα γλώσσα προγραμματισμού και περιβάλλον ανάπτυξης για άτομα που θέλουν να δημιουργήσουν εικόνες, κινούμενα σχέδια και διάφορες αλληλεπιδράσεις. Αρχικά αναπτύχθηκε σαν ένα σχεδιαστικό πρόγραμμα και για να διδάξει βασικές αρχές προγραμματισμού μέσα σε ένα οπτικό πλαίσιο, αλλά στη συνέχεια εξελίχθηκε σε ένα εργαλείο δημιουργίας ολοκληρωμένων επαγγελματικών εργασιών. Αυτή την στιγμή υπάρχουν δεκάδες χιλιάδες σπουδαστές, καλλιτέχνες, σχεδιαστές, ερευνητές και χομπίστες που χρησιμοποιούν τη Processing για διδασκαλία, προτυποποίηση και παραγωγή.

Μερικά από τα χαρακτηριστικά της Processing είναι:

  • Είναι ελεύθερο/ανοικτό λογισμικό με άδεια χρήσης GPL/LGPL.
  • Είναι πολυπλατφορμική, μπορεί να τρέξει σε λειτουργικά συστήματα GNU/Linux, Mac OS X και Windows.
  • Δημιουργεί διαδραστικά προγράμματα χρησιμοποιώντας δισδιάστατα (2D) ή τρισδιάστατα (3D) γραφικά.
  • Ενσωμάτωση της OpenGL για επιτάχυνση 3D.
  • Δημιουργία stand-alone desktop εφαρμογών και web-based εφαρμογών (applets).
  • Υπάρχουν αρκετές βιβλιοθήκες επέκτασης της γλώσσας, για εφαρμογές ήχου, βίντεο, τεχνητής όρασης, κ.α

Η Processing βασίστηκε στη δυνατότητες γραφικών της γλώσσας προγραμματισμού Java, απλοποιώντας την χρήση και δημιουργώντας νέα χαρακτηριστικά.

Έργα βασισμένα στη Processing

Η Processing είναι πηγή έμπνευσης για αρκετά έργα ανοικτού κώδικα. Δύο από τα σημαντικότερα έργα που χρησιμοποιούν την γλώσσα και το περιβάλλον της Processing είναι η Wiring και το Arduino, οι οποίες και οι δύο στοχεύουν στον απλό και άμεσο προγραμματισμό hardware. Το Arduino, σε αντίθεση με τη Wiring, δημιούργησε πλακέτες οι οποίες είναι απλές, οικονομικές και ευκολότερες στη χρήση και επέκταση, ενώ χρησιμοποιεί μία παραλλαγή της γλώσσας Processing για τον προγραμματισμό μικροελεγκτών AVR της εταιρίας Atmel. Όπως θα δούμε στο επόμενο τεύχος υπάρχει μια άριστη συνεργασία μεταξύ των πλατφορμών Arduino και Processing. Άλλα έργα που εμπνεύστηκαν από την Processing είναι τα: Design By Numbers, Fritzing, Mobile Processing, Processing.js, Spde, Processing in Clojure και Processing Monsters.

Το περιβάλλον ανάπτυξης

Από την σελίδα http://processing.org μπορούμε να κατεβάσουμε την τελευταία έκδοση της Processing. Για τα παραδείγματα αυτού του άρθρου χρησιμοποιήσαμε την έκδοση 1.2.1 της Processing. Στη συνέχεια, αφού αποσυμπιέσουμε το αρχείο, τρέχουμε το εκτελέσιμο αρχείο 'processing'. Η έκδοση για λειτουργικά συστήματα GNU/Linux περιλαμβάνει ένα ένα εκτελέσιμο αρχείο σε shell-script το οποίο εκτελείται με την εντολή ./processing. Στην εικόνα 1 βλέπουμε την διεπαφή του περιβάλλοντος ανάπτυξης, ενώ στον πίνακα φαίνονται οι βασικές λειτουργίες της εργαλειοθήκης του.


Πίνακας 1: Βασικές λειτουργίες


Εικόνα 1: Το περιβάλλον της Processing

Η δομή του προγράμματος

Ένα τυπικό πρόγραμμα στη Processing έχει την παρακάτω δομή:

// δήλωση μεταβλητών

void setup() {
// αρχικοποιήσεις
}

void draw() {
// κώδικας
}

Όπως παρατηρούμε υπάρχουν δυο βασικές συναρτήσεις σε ένα τυπικό πρόγραμμα της Processing. Η συνάρτηση setup() εκτελείται στην αρχή του προγράμματος και για μία μόνο φορά. Χρησιμοποιείται για τις αρχικοποιήσεις ιδιοτήτων και βιβλιοθηκών, όπως για παράδειγμα: το μέγεθος της οθόνης, το χρώμα φόντου, το φόρτωμα εικόνων κ.α. Οι μεταβλητές που δηλώνονται στη setup() δεν είναι προσβάσιμες από άλλες συναντήσεις, συμπεριλαμβανομένης και της draw() που θα εξηγήσουμε αμέσως μετά. Η συνάρτηση draw() εκτελείται αμέσως μετά την setup() και ο κώδικας που γράφεται μέσα στη συνάρτηση αυτή επαναλαμβάνεται συνεχώς μέχρι να τερματιστεί η εφαρμογή ή μέχρι να κληθεί η συνάρτηση noLoop().

Ας δούμε όμως την Processing με μερικά απλά παραδείγματα.

1. Βασικά σχήματα και απλό κείμενο στην Processing

Στο πρώτο παράδειγμα μας, θα δείξουμε πώς μπορούμε να δημιουργήσουμε βασικά σχήματα όπως, τετράγωνα, κύκλους, τρίγωνα και γραμμές. Επίσης θα δούμε πώς μπορούμε να τοποθετήσουμε απλό κείμενο πάνω στην εικόνα που θα δημιουργήσουμε.

Κώδικας 1


void setup() {
 size(460, 200, JAVA2D);
 colorMode(RGB, 255);
 rectMode(CORNERS);
 ellipseMode(CORNERS);
 noLoop();
}

void draw() {
 fill(255,0,0);
 rect(10,10,150,150);
 fill(0,255,0);
 ellipse(160,10,300,150);
 fill(0,0,255);
 triangle(310, 150, 450, 150, 380, 10);
 line(0, 160, 460, 160);
 fill(0,0,0);
 text("Τετράγωνο", 50, 180);
 text("Κύκλος", 210, 180);
 text("Τρίγωνο", 350, 180);
 save("example_1_1.jpg");
}

Για να τρέξουμε την εφαρμογή, επιλέγουμε από το μενού Sketch -> Run. Αμέσως θα εμφανιστούν τα τρία σχήματα που βλέπουμε στην εικόνα 2.


Εικόνα 2: Σχεδιασμός βασικών σχημάτων και απλού κειμένου.

Αν και με μια πρώτη ματιά καταλαβαίνουμε τι κάνει η κάθε εντολή, καλύτερα να εξηγήσουμε τον τρόπο λειτουργίας τους, για να καταλάβουμε καλύτερα:

  • size(x,y,renderer) – Ορίζει το μέγεθος του παραθύρου και τον renderer που θα χρησιμοποιηθεί για τον σχεδιασμό των αντικειμένων. Στο παράδειγμα χρησιμοποιείται η JAVA2D για redering γραφικών δυο διαστάσεων (x,y)
  • colorMode(RGB, 255) – Ορίζει τον τρόπο με τον οποίο η Processing μεταφράζει τα χρώματα. Στό παράδειγμα ορίζει τα χρώματα βάση του μοντέλου RGB (Red, Green, Blue) και τιμές χρώματος από 0 ως 255.
  • noLoop() - Τερματίζει την επαναληπτική εκτέλεση των εντολών που βρίσκονται εντός της συνάρτησης draw().
  • fill(r,g,b) – χρησιμοποιεί τιμές του μοντέλου RGB για το γέμισμα αντικειμένων με χρώμα.
  • rectMode() - Προσδιορίζει τον τρόπο με τον οποίο θα σχεδιαστεί ένα τετράγωνο. Υπάρχουν οι μέθοδοι CORNER, CENTER, CENTERS και RADIUS. Στο παράδειγμα χρησιμοποιείται η μέθοδος CORNERS που χρησιμοποιεί δυο σημεία για τον σχεδιασμό του τετραγώνου, το σημείο πάνω αριστερά (x1,y1) και το σημείο κάτω δεξιά (x2,y2).
  • rect(x1,y1,x2,y2) – Σχεδιάζει στην οθόνη ένα τετράγωνο χρησιμοποιώντας τη μέθοδο CORNER που είδαμε ποιο πάνω.
  • ellipseMode() - Προσδιορίζει τον τρόπο με τον οποίο θα σχεδιαστεί μία έλλειψη. Υπάρχουν οι μέθοδοι CORNER, CENTER, CENTERS και RADIUS. Στο παράδειγμα χρησιμοποιείται η μέθοδος CORNERS που χρησιμοποιεί δυο σημεία για τον σχεδιασμό της έλλειψης, το σημείο πάνω αριστερά (x1,y1) και το σημείο κάτω δεξιά (x2,y2).
  • ellipse(x1,y1,x2,y2) - Σχεδιάζει στην οθόνη μία έλλειψη χρησιμοποιώντας τη μέθοδο CORNERS που είδαμε ποιο πάνω.
  • triangle(x1,y1,x2,y2,x3,y3) - Σχεδιάζει στην οθόνη ένα τρίγωνο χρησιμοποιώντας τρία σημεία (x1,y1), (x2,y2) και (x3,y3), το κάθε σημείο αντιστοιχεί και σε μία ακμή του τριγώνου.
  • line(x1,y1,x2,y2) - Σχεδιάζει στην οθόνη μία γραμμή χρησιμοποιώντας δύο σημεία (x1,y1), (x2,y2).
  • text(text, x, y) - Τυπώνει απλό κείμενο στην οθόνη, στο σημείο (x,y).
  • save(filename) – Αποθηκεύει την τελική εικόνα στο σκληρό δίσκο. Δέχεται σαν όρισμα το όνομα και τον τύπο του αρχείου. Η Processing αποθηκεύει ψηφιακές εικόνες σε μορφή TIFF, TARGA, JPEG, και PNG.

 

2. Επεξεργασία εικόνας – χρήση πληκτρολογίου στην Processing

Σε αυτό το δεύτερο παράδειγμα θα παρουσιαστούν τα φίλτρα ψηφιακής εικόνας που υποστηρίζει η Processing. Επίσης θα γίνει χρήση του πληκτρολογίου για την εφαρμογή και εμφάνιση των φίλτρων. Για το σκοπό αυτό προγραμματίστηκαν τα αριθμητικά πλήκτρα από 1-8 ώστε πατώντας τα να εφαρμόζουν και από ένα φίλτρο.

Κώδικας 2


PImage caterpillar;

void setup() {
 size(200, 200, JAVA2D);
 colorMode(RGB, 255);
 caterpillar = loadImage("caterpillar.jpg");
}

void draw() {
 image(caterpillar, 0, 0);
 if(keyPressed) {
  if (key == '1') {
   filter(GRAY);
   save("caterpillar_grey.jpg");
  }
  if (key == '2') {
   filter(INVERT);
   save("caterpillar_invert.jpg");
  }
  if (key == '3') {
   filter(POSTERIZE, 4);
   save("caterpillar_posterize.jpg");
  }
  if (key == '4') {
   filter(BLUR, 6);
   save("caterpillar_blur.jpg");
  }
  if (key == '5') {
   filter(THRESHOLD);
   save("caterpillar_threshold.jpg");
  }
  if (key == '6') {
   filter(OPAQUE);
   save("caterpillar_opaque.jpg");
  }
  if (key == '7') {
   filter(ERODE);
   save("caterpillar_erode.jpg");
  }
  if (key == '8') {
   filter(DILATE);
   save("caterpillar_dilate.jpg");
  }
 }
}

 

Ας δούμε τώρα τις νέες εντολές που χρησιμοποιήθηκαν:

  • loadImage(filename) - Φορτώνει την εικόνα σε μία μεταβλητή τύπου Pimage. Υποστηρίζονται οι τύποι αρχείων εικόνας: .tga, .gif, .png και .jpeg. Για να φορτωθούν σωστά οι εικόνες, πρέπει να τοποθετηθούν στον φάκελο data του έργου μας.
  • Image(img, x, y) – Εμφανίζει την εικόνα στην οθόνη σε συγκεκριμένο σημείο του παραθύρου (x,y).
  • keyPressed() - Επιστρέφει '1' (αληθής) κάθε φορά που πιέζεται κάποιο πλήκτρο.
  • key - Επιστρέφει τον χαρακτήρα που πληκτρολογήθηκε
  • filter(FILTER) – Γίνεται εφαρμογή του φίλτρου στην εικόνα. Τα φίλτρα που μπορούν να χρησιμοποιηθούν μέχρι αυτή τη στιγμή είναι τα: GRAY, INVERT, POSTERIZE, BLUR, THRESHOLD, OPAQUE, ERODE και DILATE όπως φαίνονται στην εικόνα 3.

 


Εικόνα 3: Φίλτρα ψηφιακής εικόνας.

3. Σχέδια και γραφικά στην Processing

Στο τρίτο παράδειγμα, θα δημιουργήσουμε ένα απλό σχεδιαστικό πρόγραμμα, που θα εκτελεί βασικές λειτουργίες όπως: σχεδιασμό ελλείψεων, τετραγώνων, γραμμών, εισαγωγή εικόνας, ενεργοποίηση/απενεργοποίηση γεμίσματος, αποθήκευση/φόρτωμα εικόνας, επιλογή χρώματος.

Κώδικας 3


int x=0, y=0, x1=0, y1=0, x2=0, y2=0;
String create_shape="rect", str_color="blue";
color pick_color = color(0,0,255);
PFont font;
boolean fill_it=false;
PImage stamp;

void setup() {
 size(600, 400, JAVA2D);
 colorMode(RGB, 255);
 background(255,255,255);
 fill(0,0,255);
 font = loadFont("DejaVuSans-14.vlw");
 textFont(font);
 rectMode(CORNERS);
 ellipseMode(CORNERS);
 imageMode(CENTER);
}

void draw() {
 fill(255,255,255);
 noStroke();
 rect(0,0,380,25);
 fill(0,0,0);
 text("Shape:", 10, 20);
 fill(0,0,255);
 text(create_shape, 60, 20);
 fill(0,0,0);
 text("Color:", 120, 20);
 fill(0,0,255);
 text(str_color, 160, 20);
 fill(0,0,0);
 text("X:", 210, 20);
 fill(0,0,255);
 text(x, 230, 20);
 fill(0,0,0);
 text("Y:", 270, 20);
 fill(0,0,255);
 text(y, 290, 20);
 fill(0,0,0);
 text("Fill:", 330, 20);
 fill(0,0,255);
 text(int(fill_it), 360, 20);
 noLoop();
}

void mouseDragged() {
 x=mouseX;
 y=mouseY;
 loop();
}

void mousePressed() {
 x=mouseX;
 y=mouseY;
 x1=mouseX;
 y1=mouseY;
 loop();
}

void mouseReleased() {
 x2=mouseX;
 y2=mouseY;
 if(fill_it) {
  fill(pick_color);
 }
 else {
  noFill();
 }
 stroke(pick_color);
 if(create_shape=="rect") {
  rect(x1, y1, x2, y2);
 }
 if(create_shape=="ellipse") {
  ellipse(x1, y1, x2, y2);
 }
 if(create_shape=="line") {
  stroke(pick_color);
  line(x1, y1, x2, y2);
 }
 if(create_shape=="stamp") {
  image(stamp, x, y);
 }
loop();
}

void keyPressed() {
 if (key == '1') {
 create_shape = "ellipse";
 }
 if (key == '2') {
  create_shape = "rect";
 }
 if (key == '3') {
  create_shape = "line";
 }
 if (key == '4') {
  stamp = loadImage("processing.png");
  create_shape = "stamp";
 }
 if (key == '5') {
  fill_it = true;
 }
 if (key == '6') {
  fill_it = false;
 }
 if (key == 'r') {
  pick_color = color(255,0,0);
  str_color = "red";
 }
 if (key == 'g') {
  pick_color = color(0,255,0);
  str_color = "green";
 } 
 if (key == 'b') {
  pick_color = color(0,0,255);
  str_color = "blue";
 }
 if (key == 'y') {
  pick_color = color(255,255,0);
  str_color = "yellow";
 }
 if (key == 'w') {
  pick_color = color(255,255,255);
  str_color = "white";
 }
 if (key == 'n') {
  pick_color = color(0,0,0);
  str_color = "black";
 }
 if (key == 's') {
  save("data/image.jpg");
 }
 if (key == 'l') {
  PImage load_image = loadImage("data/image.jpg");
  image(load_image, 0, 0);
 }
 loop();
}

 

Οι νέες εντολές που χρησιμοποιήσαμε σε αυτό το project είναι:

  • background() - Δήλωση Χρώματος φόντου παραθύρου.
  • loadFont() - Φορτώνει την γραμματοσειρά από τον φάκελο data. Γραμματοσειρές για την Processing μπορούμε να δημιουργήσουμε αυτόματα με το εργαλείο Create Font... από το μενού Tools
  • textFont() - Δηλώνουμε τη γραμματοσειρά που θα χρησιμοποιήσουμε στο έργο μας.
  • noStroke() - Απενεργοποιεί το περίγραμμα γύρο από τα σχήματα.
  • MouseDragged() - Καλείτε κάθε φορά που ένα κουμπί του mouse μένει πατημένο και “σέρνεται” πάνω στο παράθυρο
  • noFill() - απενεργοποιεί το γέμισμα των σχημάτων με κάποιο χρώμα.
  • stroke() - Ενεργοποιεί το περίγραμμά γύρο από τα σχήματα.
  • loop() - Προκαλεί την επανειλημμένη εκτέλεση της συνάρτησης draw().
  • color() - Τύπος δεδομένων για την αποθήκευση τιμών χρώματος.
  • mousePressed() - Καλείτε για μία φορά όταν πατηθεί ένα από τα κουμπιά του mouse. Η μεταβλητή mouseButton μπορεί να χρησιμοποιηθεί για να διαπιστωθεί ποιο κουμπί του mouse έχει πατηθεί.
  • mouseReleased() - Καλείτε κάθε φορά που ένα κουμπί του mouse απελευθερώνεται.
  • mouseX – Δίνει το τρέχον σημείο του mouse στον άξονα X.
  • mouseY - Δίνει το τρέχον σημείο του mouse στον άξονα Y.

Για τον σχεδιασμό σχημάτων απλά επιλέγουμε ένα σημείο με το ποντίκι, αφήνοντας πατημένο το κουμπί ατή συνέχεια επιλέγουμε ένα άλλο σημείο και μετά το απελευθερώνουμε.


Εικόνα 4: Ένα απλό σχεδιαστικό πρόγραμμα.

Οι επιλογές των λειτουργιών γίνονται από το πληκτρολόγιο, έτσι προγραμματίσαμε τα πλήκτρα όπως φαίνεται στον Πίνακα 2.


>Πίνακας 2: Τα πλήκτρα

Δημιουργία stand-alone εφαρμογών

Η Processing μας διευκολύνει να τρέξουμε το πρόγραμμά μας σε οποιοδήποτε σύστημα ως αυτόνομη εφαρμογή, κάνοντας το export (File->Export Application). Αφού επιλέξουμε λειτουργικό σύστημα (Windows, Mac OS X ή Linux), στη συνέχεια πατάμε το κουμπί “Export”. Αμέσως δημιουργούνται στο φάκελο του έργου μας δυο φάκελοι:

ο φάκελλος “applet” περιέχει το έργο μας σε μορφή java applet, που μπορούμε εύκολα να το ανεβάσουμε σε κάποιο web server και να το τρέξουμε μέσω web browser, ενώ

ο φάκελος “application.OS” (όπου 'OS' το όνομα του λειτουργικού μας συστήματος) περιέχει ένα εκτελέσιμο script και της απαιτούμενες βιβλιοθήκες για να τρέξουμε το έργο μας χωρίς την χρήση της Processing, σαν αυτόνομη εφαρμογή. Το μόνο που απαιτείται να έχουμε εγκατεστημένο στο σύστημα είναι ο JRE (Java runtime environment)

Στην εικόνα 5 βλέπετε το τρίτο παράδειγμα να τρέχει σε web browser...


Εικόνα 5: Ενα applet της Processing

Βιβλιοθήκες και εργαλεία

Η Processing συνοδεύεται από μία πληθώρα βιβλιοθηκών και εργαλείων ανοικτού κώδικα, που σκοπό έχουν να επεκτείνουν τις δυνατότητες της γλώσσας. Υπάρχουν βιβλιοθήκες για κάθε σκοπό όπως για δημιουργία τρισδιάστατων γραφικών, δημιουργία κινουμένων σχεδίων, τεχνητή όραση, μαθηματικά, επεξεργασία ήχου, δημιουργία προσομοιώσεων κ.ά. Μπορούμε να κατεβάσουμε αρκετές βιβλιοθήκες από τη διεύθυνση http://processing.org/reference/libraries. Επίσης υπάρχουν εργαλεία τα οποία μπορούμε να τα βρούμε στο μενού “ Tools”, τα οποία μας βοηθούν σε πολλές εργασίες όπως: αυτόματη μορφοποίηση κώδικα, δημιουργία γραμματοσειρών, επιλογή χρώματος, δημιουργία συμπιεσμένου αρχείου του έργου μας κ.α.

ΣΥΜΒΟΥΛΗ

Πολλές φορές μια εντολή μπορεί να δεχτεί διαφορετικά ορίσματα, καλό είναι να συμβουλευόμαστε το reference για τη σύνταξη των εντολών της Processing. Για να ανοίξουμε το reference επιλέγουμε από το μενού Help -> Reference.

Βίντεο για την Processing

Δειτε ένα βίντεο με τις νέες δυνατότητες της Processing 3:

Περισσότερη μελέτη

Υλικό για περισσότερη μελέτη της Processing μπορούμε να βρούμε σε διάφορες διευθύνσεις στο διαδίκτυο. Επίσης υπάρχουν και αρκετά βιβλία που μπορούν να μας βοηθήσουν την ανάπτυξη εφαρμογών σε ξεκινώντας από τα βασικά. Για αρχή, μπορείτε να ακολουθήσετε τους παρακάτω συνδέσμους:

 

* Ο Γιώργος τις ελεύθερες του ώρες ασχολείται με hardware hacking σε Arduino, ενώ αρκετά συχνά ιστολογεί στο ghadjikyriacou.blogspot.com.

Δώσε αστέρια!

MO: 4 (ψήφοι: 5)