Skip to content Skip to navigation

OpenStax-CNX

You are here: Home » Content » Media Representation in Processing

Navigation

Recently Viewed

This feature requires Javascript to be enabled.
 

Media Representation in Processing

Module by: Davide Rocchesso, Pietro Polotti. E-mail the authors

Summary: Introduction on how images and sounds are represented (including colors and coordinates) in processing (in Italian).

Note: You are viewing an old version of this document. The latest version is available here.

Elementi Visuali

Coordinate

L´elaborazione grafica in processing utilizza un sistema di coordinate cartesiane 3D, come rappresentato in Figura 1.

Figura 1: Sistema di coordinate 3D in uso in processing
Sistema di coordinate
Sistema di coordinate (coordinate.png)
L´elaborazione di immagini bidimensionali si effettua agendo sul piano X-Y, assumendo quindi la coordinata Z a zero. La funzione size() definisce la dimensione della finestra di display e stabilisce quale motore di rendering sarà utilizzato per disegnare su tale finestra. Il motore di default è JAVA2D, cioè la libreria di grafica bidimensionale di Java. Se si desidera operare sulle tre dimensioni è necessario impostare il rendering P3D (Processing 3D), particolarmente efficiente per la grafica su web, oppure OPENGL, che consente di delegare alla scheda grafica molte operazioni tipiche della grafica 3D.

Immagini

In processing, una immagine può essere assegnata ad un oggetto di tipo PImage. La funzione loadImage("myImage") preleva il file (gif o jpg) myImage, contenente la codifica di una immagine, e restituisce in uscita il contenuto in pixel della immagine stessa, il quale può essere assegnato ad una variabile di tipo PImage. Il file myImage deve essere caricato nella cartella data della directory avente lo stesso nome dello sketch processing al quale si sta lavorando.

Nota:

Quando si esegue il comando New, processing apre una cartella di nome sketch_???????, all'interno di sketchbook/default, corrispondente al nome assegnato dal sistema al file al quale si comincia a lavorare. Tale cartella è accessibile tramite i comandi del menu Sketch di processing.
La classe PImage rende accessibili, mediante i campi width e height, rispettivamente la larghezza e la altezza della immagine caricata. Il contenuto è invece accessibile mediante il campo pixels[].

Esempio 1: Caricamento e visualizzazione di una immagine


	  size(400,300);
	  PImage b;
	  b = loadImage("gondoliers.jpg");
	  println("width=" + b.width + " height=" + b.height);
	  image(b, 0, 0, 400, 300); // position (0,0); width=400; height=300;
	  image(b, 20, 10, 100, 80); // position (20,10); width=100; height=80;
	

Colori

Poiché i nostri ricettori oculari di colore (coni), ciascuno sintonizzato su una regione di lunghezze d'onda, sono in numero di tre, i modelli di colore sono sempre riferiti ad uno spazio a tre dimensioni. Nei modelli di colore di tipo additivo vengono individuati tre assi coordinati, ciascuno corrispondente ad un colore base, e mediante miscelazione di tre corrispondenti fasci luminosi, si possono ottenere tutti i colori appartenenti ad un volume (gamut) individuato da tali assi. I tre colori base sono scelti in maniera arbitraria o, più spesso, sulla base del campo di applicazione (es., colore di una terna di fosfori o di laser). Nei processi di stampa si usano modelli di tipo sottrattivo, nei quali si parte da una superficie bianca e si usano inchiostri primari per sottrarre colore dal bianco.

Nota:

Guida ai modelli di colore: http://en.wikipedia.org/wiki/color_space

In processing color è un tipo primitivo usato per specificare il colore. E' realizzato mediante un numero di 32 bit, in cui il primo byte specifica il valore alpha, e gli altri byte successivi specificano una terna nel modello RGB o in quello HSB. La scelta di un modello piuttosto che dell'altro è fatta mediante la funzione colorMode(). I colori rappresentabili mediante tre byte sono in numero di 256×256×256=16777216 256 256 256 16777216 .

Modello RGB

I colori si rappresentano con una terna di numeri, ciascuno rappresentante rispettivamente le intensità dei colori primari rosso (Red), verde (Green), e blu (Blue). Ciascun numero può essere un intero senza segno e quindi assumere valori tra 0 e 255, oppure essere espresso come un numero floating point compreso tra 0 e 1.0. Queste possibilità possono essere specificate mediante la funzione colorMode(). Il modello RGB è di tipo additivo.

Modello HSB

I colori si rappresentano con una terna di numeri, ciascuno rappresentante rispettivamente la tinta o lunghezza d'onda dominante(Hue), la saturazione (Saturation), e l'intensità o brillantezza (Brightness)

Nota:
Spesso il modello viene chiamato HSV, dove la V sta per Value.
. La hue assume valori in gradi tra 0 (rosso) e 360, essendo le diverse tinte rappresentate lungo una circonferenza. Saturation e brightness variano tra 0 e 100. La saturazione è il grado di purezza del colore, quando è nulla il colore si trova sulla scala dei grigi. In termini fisici, la brillantezza è proporzionale alla potenza spettrale. Lo spazio è ben rappresentato da un cilindro, con hue (scala nominale) arrangiata lungo la circonferenza, saturation (scala rapporto) arrangiata lungo il raggio, e brightness (scala intervallo) arrangiata lungo l'asse. Oppure si da una rappresentazione bidimensionale dello spazio, come nel color chooser del programma di elaborazione di immagini Gimp, rappresentato in Figura 2.
Figura 2: Color chooser del software Gimp
Gimp color chooser
Gimp color chooser (gimp_color.gif)

Alpha channel

E' un byte di informazione usato per effettuare interpolazione tra immagini, ad esempio allo scopo di rendere la trasparenza. Esso si può ottenere, da una variabile di tipo color, con il metodo alpha. La manipolazione dell'alpha channel si svolge mediante il metodo blend() della classe PImage.

Esempio 2: Caricamento e visualizzazione di una immagine con trasparenza

Tabella 1
gondolieri.gif

          
size(400,300);
PImage b = loadImage("gondoliers.jpg");
PImage a = loadImage("gondoliers.jpg");
float ramp = 0;
for (int i = 0; i < b.width; i++)
  for (int j = 0; j < b.height; j++) {
      b.set(i, j, b.get(i,j) + 
      color(0,0,0,(int)(ramp*256)) );   
      ramp = ramp + 1/(float)(b.width * b.height); 
      }
a.blend(b, 0, 0, b.width, b.height,  
	80, 10, 450, 250, BLEND);
image(a, 0, 0, 400, 300);
          
	

In processing, è possibile assegnare un colore ad una variabile di tipo color mediante la funzione color(), essendo il modello precedentemente stato definito mediante colorMode(). Le funzioni red(), green(), blue(), hue(), saturation(), e brightness() consentono di passare da un modello all'altro.


	  colorMode(RGB,);
	  color c1 = color(102, 30,29);
	  colorMode(HSB);
	  color c2 = color(hue(c1), saturation(c1), brightness(c1));
	  colorMode(RGB);
	  color c3 = color(red(c2), green(c2), blue(c2));
	  // le variabili c1, c2, c3 contengono codifica dello stesso colore
	

Tinteggiatura di una immagine

Una immagine può essere tinteggiata con un colore e resa più o meno trasparente mediante assegnazione di un valore alpha. La funzione da usare a questo scopo è tint(). Ad esempio, per dare un tono blu all'immagine incastonata nel Tabella 1, è sufficiente far precedere il secondo comando image() da tint(0, 153,204, 126) .

Traslazioni, Rotazioni, e Trasformazioni di Scala

Rappresentazione di Punti e Vettori

In computer graphics, punti e vettori sono rappresentati in

Definition 1: Coordinate Omogenee
quaterne di numeri, in cui i primi tre vanno letti nello spazio X-Y-Z, mentre il quarto denota un vettore se assume valore 0, e denota un punto se assume valore 1.
Una traslazione si ottiene sommando, in coordinate omogenee, un vettore a un punto, ed il risultato è, ovviamente, un punto. Oppure, si può vedere la traslazione come un prodotto matrice-vettore, dove la matrice è ( 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ) 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 , e il vettore è quello che rappresenta il punto xyz1 x y z 1 . Una rotazione antioraria di un angolo θ θ rispetto all'asse z z (roll o rollio), viene realizzata mediante la matrice di rotazione ( cosθsinθ0 0 sinθcosθ0 0 0 0 1 0 0 0 0 1 ) θ θ 0 0 θ θ 0 0 0 0 1 0 0 0 0 1 . Rotazioni rispetto agli assi x x (pitch o beccheggio) e y y (yaw o imbardata) si realizzano con matrici di rotazione di tipo analogo, e la rotazione rispetto ad un asse arbitrario si può realizzare mediante composizione (moltiplicazione a sinistra) di rotazioni elementari rispetto a ciascun asse.

Traslazioni

La funzione translate() consente di spostare oggetti sulla finestra di immagine. Ammette due o tre argomenti, che sono rispettivamente gli spostamenti lungo le direzioni x x, y y (e z z).

Rotazioni

In due dimensioni, la funzione rotate() consente di ruotare oggetti sulla finestra di immagine. Ciò avviene mediante una moltiplicazione (a sinistra) delle coordinate di ciascun pixel dell'oggetto non ruotato per una matrice di rotazione. La rotazione avviene sempre rispetto all'angolo superiore sinistro (coordinate 00 0 0 ), e quindi va opportunamente accompagnata da una traslazione. L'angolo di rotazione viene fornito secondo la misura in radianti. Si ricordi che 2 π rad = 360 ˚ 2 rad 360 ˚ . Ad esempio, si inserisca la rotazione rotate(PI/3) prima del secondo comando image() in Tabella 1. In tre dimensioni, si possono usare le rotazioni elementari rispetto agli assi coordinati rotateX(), rotateY(), e rotateZ().

Trasformazioni di Scala

La funzione scale() consente di espandere o contrarre un oggetto mediante moltiplicazione per una costante delle coordinate dei punti che lo compongono. Se invocata con due o tre parametri, gli scalamenti possono anche essere diversi lungo i diversi assi cartesiani.

Elementi Uditivi

Suoni

Processing non fornisce solamente un ambiente per la programmazione grafica, ma prevede anche la possibilità di utilizzare diverse funzionalità audio. Nella versione Beta attuale (20 aprile 2005) sono disponibili due primitive di base, che consentono la semplice riproduzione dei file .wav: PSound e loadSound(). Quest'ultima permette di caricare un suono in una variabile di tipo PSound predefinita. Si possono caricare solo file .wav. Per poterli importare, i file di suono devono essere archiviati nella directory "data" dello sketch corrente. La sintassi è soundA = loadSound(filename), dove soundA è una variabile di tipo PSound. Per riprodurli i comandi a disposizione sono soundA.play(); oppure soundA.loop();, se si vuole far suonare il campione in circolo.

Una collezione di primitive più ricca è invece raccolta all'interno di una libreria esterna denominata Sonia. Tale libreria contiene, per esempio, delle funzioni che permettono di riprodurre campioni audio (sample playback), di eseguire un'analisi di Fourier in tempo reale (ovvero un'analisi del suono che viene captato da un microfono collegato al computer: realtime FFT), nonchè di salvare dei file .wav sul disco. Per poter utilizzare la libreria Sonia è necessario scaricare il file .zip dal sito http://pitaru.com/sonia/. Bisogna poi decomprimere il tutto e copiare la directory "Sonia_2_9" dentro la directory "Processing/libraries". Infine, dopo aver riavviato Processing, per poter usufruire delle risorse di Sonia, si deve aggiungere un comando import, selezionandolo direttamente dal menu "Sketch -> Import Library -> Sonia_2_9"

Nota:

Sonia utilizza il plugin JSyn plugin di Phil Burk che può essere scaricato e installato dal sito http://www.softsynth.com/jsyn/plugins/ .
Come nel caso della primitiva loadSound(), per poter utilizzare dei campioni audio è necessario copiarli all'interno della cartella data, così come fatto nel caso delle immagini. A questo punto siamo pronti per poter imparare a lavorare con il suono in Processing.

Timbri

In questa sezione del modulo proveremo prima ad utilizzare e poi ad analizzare un'applicazione per l'esplorazione dei timbri, simile nella concezione al Color Chooser di Figura 2, denominata Sound Chooser. Per adesso possiamo pensare al timbro di un suono come al "colore" di un'immagine. O se si vuole possiamo pensare al timbro come al diverso "colore" dei diversi strumenti. Più avanti nel corso vedremo con maggior precisione a cosa corrispondono dal punto di vista fisico e percettivo sia il colore sia il timbro. Nella applet sound chooser si possono far suonare 4 suoni con timbri diversi, facendo click con il mouse su uno qualsiasi dei raggi. Ciascuno dei raggi corrisponde ad uno strumento musicale (timbro/colore) diverso. Cambiando posizione lungo il raggio e facendo click, è possible sentire come la brillantezza del timbro corrispondente cambia. Più precisamente, man mano che si procede verso il centro, il suono si fa vieppiù povero.

Trasformazioni

Vediamo ora in cosa consiste il codice Processing necessario per implementare il Sound Chooser nei tratti salienti. Il comando Sonia.start(this) è indispensabile per attivare il motore audio di Sonia. La linea Sample mySample1 dichiara una variabile atta a contenere campioni audio. A tale variabile possono essere applicati vari metodi, tra i quali il metodo play per riprodurre il campione. Nel draw() viene definito l'aspetto grafico della applet. Infine, tramite la funzione mouseReleased() viene rilevato quando il mouse viene rilasciato dopo essere stato premuto e in quale area del cerchiello. A quel punto una successione di condizioni if stabilisce quale strumento/timbro debba essere riprodotto a seconda del punto di interazione. Inoltre, all'interno della funzione mouseReleased() viene invocata un'altra funzione: filtra(float[] DATAF, float[] DATA, float RO, float WC). Questa funzione, che viene implementata alla fine del listato di questa applet, esegue un filtraggio sul suono che viene riprodotto. In particolare si tratta di un filtraggio passa-basso, vale a dire che lascia passare le basse frequenze ma non le alte. A seconda se il mouse viene rilasciato più o meno vicino al centro, l'effetto del filtraggio cambia. Più precisamente il filtraggio sarà più marcato (ovvero le alte frequenze saranno maggiormente attenuate, con l'effetto di un maggior incupimento del suono), se il mouse viene rilasciato in prossimità del centro e il suono risulterà più povero (scolorito).

Tabella 2
Sound Chooser: Applet che permette di scegliere un timbro e modificarne la brillantezza (brightness)

                 
Sample mySample1, mySample2, mySample3, mySample4; 
Sample mySample1F, mySample2F, mySample3F, mySample4F;

float[] data1, data2, data3, data4;
float[] data1F, data2F, data3F, data4F; 

float ro;
float roLin;
float wc;

int sr = 44100;

void setup() 
{
  size(200, 200);
  colorMode(HSB, 360, height, height);  
  Sonia.start(this);
 
  mySample1 = new Sample("flauto.aif");
// ... OMISSIS ...  
  mySample1F = new Sample("flauto.aif");
// ... OMISSIS ...
 data1  = new float[mySample1.getNumFrames()]; 
	  //creates a new array the length of the sample
// ... OMISSIS ...
  data1F  = new float[mySample1.getNumFrames()]; 
	  //creates a new array the length of the sample
// ... OMISSIS ...
 
  mySample1.read(data1);
  mySample2.read(data2);
  mySample3.read(data3);
  mySample4.read(data4);  
} 
 
void draw() 
{
// ... OMISSIS ...
}

void mouseReleased() 
{
 
// FLAUTO
if ((mouseX > 95) && (mouseX < 105)&& (mouseY > 50)&& (mouseY < 90)) {
     
    roLin = (mouseY-49.99)/40;
    ro = pow(roLin,.33);
    println("ciccio=" + ro + "   "+ "Y=" + mouseY);
    wc = 298*(TWO_PI/sr);
    filtra(data1F, data1, wc, ro);  

    mySample1F.write(data1F);
    mySample1F.play();
    }
     
// OBOE
// ... OMISSIS ...

// TROMBA    
// ... OMISSIS ...

// VIOLINO        
// ... OMISSIS ...
  
}


//filtra = new function
void filtra(float[] DATAF, float[] DATA, float WC, float RO) {

    float G;
    float RO2;  
    RO2 = pow(RO, 2);
    G = (1-RO)*sqrt(1-2*RO*cos(2*WC)+RO2)*4; // (*4) is for having it louder
    println("ro=" + RO +" "+ "wc=" + WC);   

    for(int i = 3; i < DATA.length; i++){ 
      DATAF[i] = G*DATA[i]+2*RO*cos(WC)*DATAF[i-1]-RO2*DATAF[i-2];//filtraggio ricorsivo      }
}


// safely stop the Sonia engine upon shutdown. 
public void stop(){ 
  Sonia.stop(); 
  super.stop(); 
} 
             	      
	    

Exercise 1

Completare il codice riportato in tabella per ottenere l'applet Sound Chooser completa.

Solution

In un modulo separato.

Exercise 2

Aggiungere ai raggi del Sound Chooser del colore, sostituendo le line con dei rect e colorando le barrette ottenute con una variazione di saturazione, crescente dal centro verso l'esterno.

Solution

In un modulo separato.

Content actions

Download module as:

Add module to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks