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.