◩ Grafica e immagini

Correzione gamma e luce lineare: perché le sfumature escono scure

Cos'è la gamma, perché i valori sRGB non sono proporzionali alla luce e come lavorare in spazio lineare per sfumature, fusioni e ridimensionamenti.

Provate a creare una sfumatura dal rosso puro al verde puro con un semplice calcolo di media tra i valori RGB. Al centro comparirà una banda marrone scuro, che nella realtà non esisterebbe mescolando due luci. Oppure ridimensionate una foto con sottili linee bianche su fondo nero: dopo la riduzione appare più scura dell'originale. Entrambi i problemi hanno la stessa causa, la gamma, ed è uno degli argomenti più fraintesi della grafica digitale.

La percezione non è lineare

L'occhio umano non percepisce la luminosità in proporzione alla quantità di luce. Siamo molto più sensibili alle differenze nelle zone scure che in quelle chiare: passare da una a due candele in una stanza buia è un cambiamento enorme, passare da cento a centouno è impercettibile.

Se si codificasse la luce in modo lineare con 8 bit, cioè con 256 livelli equidistanti in termini di energia, si sprecherebbero moltissimi livelli nelle alte luci, dove l'occhio non distingue le differenze, e se ne avrebbero troppo pochi nelle ombre, dove comparirebbero gradini visibili.

La soluzione: codifica con una curva

Per usare meglio i bit disponibili, i valori vengono memorizzati dopo aver applicato una curva che "espande" le ombre e "comprime" le luci. In modo semplificato:

valore_codificato = luce_lineare ^ (1 / 2,2)
luce_lineare      = valore_codificato ^ 2,2

Lo standard sRGB usa in realtà una funzione a tratti, con un piccolo segmento lineare vicino al nero e una potenza di 2,4 per il resto, ma nel complesso si comporta in modo simile a una gamma di 2,2. Con valori normalizzati tra 0 e 1, il valore codificato 0,5 corrisponde a circa il 21% della luce del bianco.

Valore sRGB (8 bit) Luce lineare approssimativa
0 0%
64 circa 5%
128 circa 22%
188 circa 50%
255 100%

Il grigio che appare "a metà" tra nero e bianco emette dunque circa un quinto della luce. E per ottenere metà della luce del bianco serve un valore intorno a 188.

Dove la gamma crea problemi

La codifica gamma è ottima per memorizzare e trasmettere immagini. Diventa un problema quando si eseguono calcoli fisici sui valori codificati come se fossero luce. I casi tipici sono:

  • Sfumature: interpolare tra due colori sui valori sRGB produce zone centrali troppo scure e a volte desaturate.
  • Fusione di livelli e trasparenze: un livello bianco al 50% su nero dovrebbe produrre un grigio che emette metà della luce, ma il calcolo diretto dà il valore 128, che ne emette un quinto.
  • Ridimensionamento: fare la media di pixel chiari e scuri in spazio gamma scurisce i dettagli fini; testi chiari su fondo scuro e foto di stelle sono gli esempi più evidenti.
  • Sfocatura: le luci puntiformi sfocate in spazio gamma diventano macchie spente invece di dischi luminosi, come accadrebbe in un vero obiettivo.
  • Illuminazione 3D: sommare luci su valori gamma produce scene con contrasto innaturale.

Lavorare in spazio lineare

La procedura corretta per questi calcoli è sempre la stessa:

  1. Decodificare: convertire i valori sRGB in luce lineare, applicando la funzione inversa.
  2. Calcolare: eseguire media, fusione, sfocatura o illuminazione sui valori lineari.
  3. Ricodificare: riapplicare la curva sRGB prima di salvare o mostrare.

Lavorando in lineare servono più bit: con soli 8 bit per canale le ombre si riempirebbero di gradini. Per questo i programmi che operano in spazio lineare usano internamente 16 bit interi o numeri in virgola mobile.

Nella pratica:

  • i software 3D e i motori di gioco moderni calcolano l'illuminazione in lineare e convertono solo all'uscita;
  • molti programmi di fotoritocco offrono un'opzione per la fusione dei colori con gamma 1,0 o per lavorare in uno spazio lineare;
  • le schede video supportano formati di texture "sRGB" che vengono decodificati automaticamente alla lettura e codificati alla scrittura, a costo zero.

Un esempio concreto

Nel mio lavoro ho visto spesso miniature generate da script automatici in cui i caratteri bianchi su fondo scuro diventavano grigi e quasi illeggibili. Il codice faceva la media dei pixel direttamente sui valori sRGB. Convertire in lineare prima del ridimensionamento e tornare in sRGB dopo ha risolto il problema senza altri cambiamenti. È un intervento di poche righe, ma va ricordato che ogni libreria ha il proprio comportamento predefinito: alcune lavorano già in lineare, altre no.

Gamma del monitor e gamma del file

Una precisazione per evitare confusione: si parla di "gamma" anche per la risposta del monitor. Per decenni gli schermi a tubo catodico avevano naturalmente una risposta simile a una potenza di circa 2,2–2,5, e la codifica dei segnali si è adattata a quella caratteristica. Gli schermi moderni non hanno questo comportamento fisico, ma lo emulano per restare compatibili. Il risultato è che, se tutto è configurato correttamente, la codifica del file e la risposta dello schermo si compensano e l'immagine appare come previsto.

In sintesi

  • L'occhio è più sensibile alle differenze nelle ombre: per questo i valori sono codificati con una curva gamma.
  • In sRGB il valore 128 corrisponde a circa un quinto della luce del bianco, non alla metà.
  • Sfumature, fusioni, ridimensionamenti, sfocature e illuminazione vanno calcolati in luce lineare.
  • Il metodo è sempre decodificare, calcolare, ricodificare, con più di 8 bit durante il calcolo.
  • La gamma del file e quella dello schermo, se configurate bene, si compensano.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche