Una palette di colori da un’immagine

Nelle ultime settimane mi è capitato di fare diversi lavori di grafica – che non è propriamente il campo in cui sono più ferrato – e mi sono sempre trovato in crisi nella scelta della palette di colori più adatta a quello che stavo facendo.

Mentre ero alla ricerca della giusta combinazioni di colori su siti come Coolors e Adobe Color mi è tornata in mente una frase di Joshua Davis detta in uno dei suoi video (non cito testualmente, vado a memoria): le palette di colori che funzionano meglio sono quelle legate a immagini a cui siamo abituati, come un tramonto sul mare oppure le gradazioni di verde in un bosco in montagna. Ecco perché estrarre i colori da una foto è uno dei modi migliori per trovare delle combinazioni che funzionano.

Da qui l’illuminazione: perché non creare uno sketch in Processing per aiutarmi?

Leggere i colori da un’immagine

Partiamo riciclando il codice visto nell’ultimo post: Modificare la dimensione della finestra in base all’immagine caricata. Creiamo un oggetto di tipo PImage e facciamo in mondo che la finestra si ridimensioni automaticamente al caricamento del file. Nel codice sotto riportato noterete un +50 pixel nell’altezza che servirà come spazio per rappresentare i colori della palette in tempo reale.

Per questo sketch ho deciso di utilizzare l’immagine di un prato fiorito:Leggere i colori da un'immagine con Processingricordatevi di inserire l’immagine nella cartella /data come spiegato qui.

Creiamo due variabili di tipo integer: la prima, numPoints indica il numero di colori di cui sarà composta la nostra palette. Ho deciso di chiamarla points perché prenderemo i dati colori da dei punti nell’immagine. La seconda pointX la utilizzeremo come riferimento per calcolare il valore di x dei punti scelti che, ai fini di questo esempio, saranno equidistanti.

Aggiungiamo un po’ di codice nel ciclo draw(): mostriamo l’immagine come sfondo e carichiamo l’array di pixel. Come anticipato, assegniamo a pointX il valore della larghezza della foto caricata diviso il numero di punti.

Utilizziamo il classico ciclo for per trovare i colori dei punti. Creo un minimo di interfaccia per aiutarmi nel lavoro: intorno ai punti di riferimento disegno un cerchio.

Avendo deciso di lasciare il valore di y variabile e dipendente dalla posizione y del mouse, ho deciso di inserire un controllo condizionale per verificare di non uscire dall’immagine stessa causando un errore Array out of bounds sull’array di pixel.

Nella console vengono mostrati i valori di c ma non sono utilizzabili in alcun programma di grafica perché non sono i classici valori HEX, RGB o HSB.

Mostriamo la palette di colori

Sfrutto i 50 pixel di margine di abbondanza rispetto alla foto per mostrare in tempo reale i colori dei pixel di riferimento. Farlo è molto semplice: creo dei rettangoli con, come fill, il colore estratto in precedenza. Sfrutto questo passaggio per centrare i punti di analisi rispetto alla larghezza della finestra e ai rettangoli in basso.

Palette di colori da immagine

Otteniamo i valori HEX dei colori

A questo punto il programma funziona nel modo corretto, non ci resta che fare dei piccoli miglioramenti all’interfaccia: grazie alla funzione hex(value, digits) possiamo ottenere il valore esadecimale del colore. Come indicato nel reference, il numero viene rappresentato con un massimo di 8 caratteri ma possiamo ottenerne 6, come siamo abituati, aggiungendo indicando il secondo parametro alla funzione.

Palette colori GIF

Ecco qui il codice:

Salvare la palette di colori in un file di testo

Siamo quasi alla fine del nostro lavoro: l’unico passaggio che ci manca è salvare la palette di colori in un file .txt in modo da poterli usare a nostro piacimento anche in programmi esterni.

Aggiungiamo qualche riga di codice: creiamo una nuova variabile di tipo StringList il cui contenuto verrà inizializzato a ogni ciclo di draw con la funzione .clear();

Alla pressione del tasto del mouse, verrà salvato il file chiamato palette.txt. La conversione della StringList in array è necessaria perché la funzione saveStrings si aspetta come secondo parametro un array e non una lista.