Arte generativa con Processing

Transcript

Arte generativa con Processing
Ugo Betori
Multimedia design
www.ugobetori.it
[email protected]
Multimedia design
Ugo Betori offre servizi e consulenza
per la grafica, il web e il mobile
design. Progetta e realizza siti
web, soluzioni e-commerce,
applicazioni per dispositivi mobile.
Consulente, tiene corsi di formazione
e aggiornamento. Collabora con il
portale HTML.it e con la casa editrice
Edizioni Master.
Grafica
Web design
E-commerce
Mobile design
Interactive design
Illustrazione
Rendering 3D
Consulenza
Training
Processing.js è l’ennesima fatica di John Resig,
team leader del famoso framework jQuery.
Processing.js è un linguaggio di programmazione
aperto destinato a chiunque voglia programmare
utilizzando immagini, animazioni, e interazioni
avanzate senza affidarsi a tecnologie proprietarie
come, ad esempio, Adobe Flash, o a linguaggi
di programmazione più strutturati e complessi
quali Java. Grazie a Processing.js è sufficiente
avere una conoscenza base di Javascript per
disegnare forme e manipolare immagini utilizzando
l’elemento canvas di HTML5. Il codice è leggero,
semplice da imparare, ed è ideale per creare effetti
particolari e piccoli “sketch” di computer art, ma le
sue potenzialità consentono anche di visualizzare
dati, creare interfacce lato utente, sviluppare
applicazioni e persino giochi. Processing.js è
sviluppato esplicitamente per i browser che
supportano le specifiche HTML5 come l’elemento
Canvas. Attualmente viene quindi eseguito
su Firefox, Safari, Opera e Chrome ma non è
supportato da Internet Explorer 8.
1. Disegnare con Processing.js
Processing.js può essere scaricato dalla sua pagina presso http://processingjs.org/. Una volta estratto l’archivio,
per iniziare rapidamente si può, ad esempio, creare un file JavaScript in cui scrivere il seguente codice utile a
disegnare un quadrato rosso:
void setup() {
size(400, 400);
}
void draw() {
background(#ff0000);
}
Per prima cosa è necessario dichiarare la funzione setup() mediante la quale si impostano le proprietà di
visualizzazione quali dimensione del canvas, colori e spessori delle figure, la velocità di esecuzione (frame rate), ecc.
Il passo successivo consiste nel definire la funzione draw() la quale controlla cosa verrà disegnato in ogni frame
dell’animazione. Occorre sottolineare subito che la funzione draw() continua ad essere eseguita in ciclo continuo fino
a quando non si interrompe esplicitamente con la chiamata del metodo exit().
Quindi, il codice d’esempio imposta un canvas con dimensioni 400x400 pixel e disegna il background del canvas
stesso con un colore rosso. Per visualizzare il risultato nel browser occorre creare la pagina HTML in cui richiamare il
plugin Processing.js, nella sezione <head> del documento:
<script src=”processing-1.0.0.js”></script>
Nel tag <body> si andrà invece a definire l’elemento canvas:
<canvas datasrc=”redbox.js” width=”400” height=”400”></canvas>
Avendo l’accortezza di specificare per la proprietà datasrc il percorso del file javascript contenente il codice.
2. Animazione e interattività
Processing.js consente di aggiungere effetti di animazione e un discreto grado di interattività agli elementi presenti
nel canvas. Aggiungere interattività è piuttosto semplice. La libreria infatti fornisce un buon numero di funzioni a
tale scopo. Ad esempio, mousePressed() che controlla gli eventi relativi all pressione del mouse, o mouseMoved()
grazie al quale definire come rispondere al movimento del mouse da parte dell’utente. Oltre a ciò, Processing.js
dispone di proprietà altrettanto utili e di semplice utilizzo: mouseX e muoseY, ad esempio, forniscono informazioni
riguardo la posizione attuale del mouse lungo gli assi X e Y del canvas. Ecco un semplice esempio di animazione
interattiva:
float raggio = 50.0;
int X, Y;
int newX, newY;
int ritardo = 16;
Si vuole realizzare un cerchio colorato che segue il movimento del mouse. Nel primo blocco di codice si dichiarano
alcune variabili, quali il raggio del cerchio, le sue posizioni lungo gli assi X e Y, le nuove posizioni che di volta in
volta andrà a prendere e un valore di ritardo per rendere più morbida l’animazione. Nel blocco successivo si lancia il
metodo setup():
void setup(){
size(400, 400);
strokeWeight(6);
frameRate(16);
X = width/2;
Y = height/2;
}
dove si definisce la posizione di partenza del cerchio, al centro del canvas.
Nel metodo draw() si realizza la maggior parte del lavoro:
void draw(){
background(255);
fill(0, 121, 184);
stroke(100);
ellipse( X, Y, raggio, raggio );
X+=(newX-X)/ritardo;
Y+=(newY-Y)/ritardo;
}
Qui infatti si impostano i colori, si disegna il cerchio grazie al metodo ellipse() e si assegna ad esso la posizione,
calcolando la differenza tra l’attuale posizione (X, Y) e quella nuova (newX, newY) e dividendo il risultato per il valore
di ritardo. Facendo questo è bene ricordare che tutto quanto scritto nel metodo draw() si ripete continuamente alla
velocità, in questo caso, di 16 fotogrammi al secondo.
Infine si definisce la nuova posizione del cerchio:
void mouseMoved(){
newX = mouseX;
newY = mouseY;
}
Questa viene rilevata ad ogni movimento del mouse ed è quindi impostata come nuova posizione del cerchio.
3. Arte e codice
Per concludere questa introduzione a Processing.js, si proverà a realizzare qualcosa di più astratto: si vuole lavorare
con un’immagine bitmap a cui applicare un effetto di spostamento dei relativi pixel.
PImage miaImmagine;
int[] arrayPixel = new int[800*300];
int direzione = 1;
float scanner;
In questo primo blocco si impostano alcune variabili che verranno utilizzate successivamente, tra cui un array e la
variabile scanner. Quest’ultima rappresenta una linea orizzontale che scorrerà su e giù lungo l’immagine leggendo i
valori cromatici dei singoli pixel presenti lungo l’asse X dell’immagine.
Nel metodo setup(), dopo aver caricata l’immagine, si assegnano al suddetto array i valori dei pixel presenti
nell’immagine stessa:
void setup() {
size(800, 300);
stroke(255);
frameRate(8);
miaImmagine = loadImage(“data/pavel.jpg”);
for(int i=0; i<width*height; i++) {
arrayPixel[i] = miaImmagine.pixels[i];
}
}
Quindi nel metodo draw() si definisce il codice di trasformazione:
void draw() {
scanner += (1*direzione);
if (scanner > height-1 || scanner < 0) {
direzione = direzione * -1;
}
loadPixels();
for (int i=0; i<width*height; i++) {
pixels[i] = arrayPixel[int((width*int(scanner))+(i%width))];
}
updatePixels();
}
In sintesi, nella prima riga del blocco si imposta la velocità di spostamento dello scanner lungo l’asse Y. Quindi
mediante una verifica if() si controlla che la linea dello scanner non esca dai margini superiore e inferiore
dell’immagine stessa. Questo il dettaglio:
if (scanner > height-1 || scanner < 0) {
direzione = direzione * -1;
}
Ogni volta che lo scanner raggiunge uno dei due limiti, il codice inverte la direzione del suo spostamento.
Nel passo successivo vengono caricati i pixel dell’immagine mediante il metodo loadPixels() e si chiama un ciclo
for() che legge il valore dei singoli pixel presenti nella linea orizzontale dello scanner e li assegna ai pixel della
visualizzazione lungo tutto l’asse verticale, ottenendo un effetto di trascinamento.
Fatto questo, si aggiorna la visualizzazione con il metodo updatePixels().
4. Da Processing.js a Processing e viceversa
Processing.js è il porting in JavaScript di Processing, framework che, come linguaggio di programmazione, utilizza
il più complesso Java. Creato appositamente per le comunità di designers e sviluppator, il suo obiettivo principale è
quello di “insegnare le tecniche di programmazione ai non-programmatori attraverso l’immediata gratificazione data
dai risultati visuali”. Processing è stato creato da Ben Fry e Casey Reas. Tutto è partito da alcune idee discusse nel
gruppo “Aesthetics and Computation” al MIT Media Lab, e all’origine fu pensato per essere usato in ambiente Java.
Processing include il cosiddetto “sketchbook”, un’alternativa minimale al classico IDE (integrated development
environment ) per l’organizzazione dei progetti in ambito di programmazione. Il processo di sviluppo prevede infatti
che le varie creazioni (chiamate sketch) siano organizzate in uno sketchbook . Ogni sketch contiene in genere, oltre
alle classi di oggetti che lo compongono, una cartella in cui inserire i file multimediali (immagini, font, audio, ecc.) utili
all’applicazione. Una volta creata l’applicazione questa può inoltre essere esportata anche in forma di Java applet.
Processing è distribuito sotto licenza Open Source, ed è supportato dai sistemi operativi GNU/Linux, Mac OS
X e Windows. Da una costola di Processing è nato pure i progetto Mobile Processing, che consente di creare
applicazioni per dispositivi mobile che utilizzano la tecnologia Java, sfruttando il Sun Java Wireless Toolkit. Maggiori
dettagli si possono trovare presso il sito ufficiale www.processing.org.