Quando apriamo una foto sul telefono vediamo volti, paesaggi, colori. Il computer, invece, vede soltanto una tabella di numeri. Capire com'è fatta questa tabella è il primo passo per ragionare in modo corretto su formati, compressione, ridimensionamento e qualità. In questo articolo smonto un'immagine raster pezzo per pezzo, senza dare nulla per scontato.
Una griglia di campioni
Un'immagine raster (detta anche bitmap) è una matrice rettangolare: ha una larghezza e un'altezza espresse in pixel, e ogni cella della matrice contiene un valore. Una foto da 4000 × 3000 pixel ha quindi 12 milioni di celle, cioè 12 megapixel.
Il termine pixel deriva da picture element. È utile pensarlo non come un quadratino colorato, ma come un campione: la misura della luce in un punto della scena. Il quadratino è solo il modo più semplice in cui uno schermo mostra quel campione. Questa distinzione non è pedanteria: spiega perché ingrandire un'immagine non aggiunge dettaglio e perché esistono metodi diversi per ricostruire i valori "tra" un campione e l'altro.
Cosa c'è dentro un pixel
Il contenuto di ogni cella dipende dal tipo di immagine.
- Scala di grigi: un solo numero per pixel, che rappresenta la luminosità. Con 8 bit si hanno 256 livelli, da 0 (nero) a 255 (bianco).
- Colore RGB: tre numeri per pixel, uno per il rosso, uno per il verde e uno per il blu. Ognuno di questi è un canale.
- RGBA: ai tre canali di colore si aggiunge un canale alfa che indica l'opacità.
- Indicizzata (a palette): ogni pixel contiene un indice che rimanda a una tabella di colori. È il principio delle GIF e delle PNG a palette.
Con 8 bit per canale, un pixel RGB occupa 24 bit e può assumere circa 16,7 milioni di combinazioni (256 × 256 × 256). Sembra moltissimo, ma vedremo in altri articoli che in certe sfumature non basta.
Quanto pesa un'immagine non compressa
Il calcolo è semplice e vale la pena saperlo fare a mente:
byte = larghezza × altezza × canali × (bit per canale / 8)
Una foto 4000 × 3000 in RGB a 8 bit occupa 4000 × 3000 × 3 = 36 milioni di byte, circa 34 MiB. La stessa immagine a 16 bit per canale raddoppia, superando i 68 MiB. Il file JPEG che troviamo sulla scheda di memoria pesa magari 5 MB: la differenza è tutta merito della compressione.
Questo calcolo serve anche nel lavoro quotidiano. Quando un programma di editing rallenta con molti livelli aperti, il motivo è che ogni livello è, in memoria, una matrice completa non compressa. Dieci livelli di quella foto a 16 bit con canale alfa superano facilmente il gigabyte.
Come sono disposti i dati in memoria
Una matrice bidimensionale in memoria diventa una sequenza lineare di byte. Esistono due disposizioni principali:
| Disposizione | Ordine dei dati | Uso tipico |
|---|---|---|
| Interleaved (a pixel) | R G B R G B R G B… | La maggior parte dei formati e delle API grafiche |
| Planare | tutti i R, poi tutti i G, poi tutti i B | Alcune elaborazioni scientifiche e video |
C'è poi l'ordine dei canali: non tutti i sistemi usano RGB. Alcune librerie storiche lavorano in BGR, e chi scrive codice di elaborazione se ne accorge quando i cieli diventano arancioni. Infine, molte librerie aggiungono byte di riempimento alla fine di ogni riga per allineare i dati in memoria: la lunghezza effettiva di una riga si chiama stride o pitch e può essere maggiore di larghezza × byte per pixel.
Pixel dello schermo e pixel dell'immagine
Un'altra fonte di confusione: i pixel del file non coincidono necessariamente con i pixel fisici del monitor. Uno schermo ad alta densità può usare due o tre pixel fisici per ogni "pixel logico" dell'interfaccia. Quando visualizziamo una foto al 100% in un programma di editing, di solito vediamo un pixel dell'immagine per ogni pixel fisico; nelle pagine web e nelle app, invece, entra in gioco un fattore di scala. Per questo un'icona da 32 pixel può apparire sfocata su uno schermo moderno se non ne esiste una versione a densità doppia.
Perché tutto questo conta
Sapere che un'immagine è una griglia di campioni numerici permette di rispondere da soli a molte domande pratiche:
- Posso ingrandire una foto piccola senza perdere qualità? No: i campioni sono quelli, si può solo stimare cosa c'è in mezzo.
- Perché ritagliare riduce il peso del file? Perché si eliminano celle della matrice.
- Perché convertire in bianco e nero riduce la memoria? Perché si passa da tre canali a uno.
- Perché ruotare di 10 gradi peggiora leggermente l'immagine? Perché la nuova griglia non coincide con quella vecchia e i valori vanno ricalcolati.
Nel mio lavoro di analisi di file digitali questa visione "numerica" è fondamentale: ogni operazione sull'immagine lascia tracce nei valori dei pixel, e ragionare su numeri invece che su impressioni visive rende l'analisi più rigorosa.
In sintesi
- Un'immagine raster è una matrice di campioni: larghezza × altezza celle, ognuna con uno o più canali.
- Il peso non compresso si calcola come larghezza × altezza × canali × byte per canale.
- I dati possono essere interleaved o planari, in ordine RGB o BGR, con eventuale riempimento di riga.
- I pixel dell'immagine e quelli dello schermo sono cose diverse, legate da un fattore di scala.