Una motivazione principale per il formato PNG era quella di creare un sostituto per GIF che non fosse solo gratuito ma anche un miglioramento su di esso in sostanza sotto tutti gli aspetti. Di conseguenza, la compressione PNG è completamente senza perdita di dati, ovvero i dati dell'immagine originale possono essere ricostruiti esattamente, bit per bit, proprio come in GIF e nella maggior parte delle forme di TIFF.
PNG utilizza un processo di compressione in 2 fasi:
- Pre-compressione: filtro (previsione)
- Compressione: DEFLATE (vedi Wikipedia )
La fase di precompressione si chiama filtro, che è un metodo per trasformare in modo reversibile i dati dell'immagine in modo che il motore di compressione principale possa funzionare in modo più efficiente.
Come semplice esempio, considera una sequenza di byte che aumenta uniformemente da 1 a 255:
1, 2, 3, 4, 5, .... 255
Dal momento che non c'è ripetizione nella sequenza, si comprime molto male o non lo è affatto. Ma una banale modifica della sequenza - vale a dire, lasciando solo il primo byte ma sostituendo ogni byte successivo con la differenza tra esso e il suo predecessore - trasforma la sequenza in un set estremamente comprimibile:
1, 1, 1, 1, 1, .... 1
La trasformazione di cui sopra è senza perdita, poiché non sono stati omessi byte ed è completamente reversibile. Le dimensioni compresse di questa serie saranno molto ridotte, ma le serie originali possono ancora essere perfettamente ricostituite.
I dati reali delle immagini raramente sono così perfetti, ma il filtraggio migliora la compressione nelle immagini in scala di grigi e truecolor e può aiutare anche su alcune immagini di palette. PNG supporta cinque tipi di filtri e un codificatore può scegliere di utilizzare un filtro diverso per ogni riga di pixel nell'immagine:
L'algoritmo funziona su byte, ma per pixel di grandi dimensioni (ad esempio RGB a 24 bit o RGBA a 64 bit) vengono confrontati solo i byte corrispondenti, il che significa che i componenti rossi dei colori dei pixel vengono gestiti separatamente dai componenti dei pixel verde e blu.
Per scegliere il filtro migliore per ogni riga, un codificatore dovrebbe testare tutte le possibili combinazioni. Ciò è chiaramente impossibile, poiché anche un'immagine di 20 righe richiederebbe test su oltre 95 trilioni di combinazioni, in cui il "testing" implicherebbe il filtraggio e la compressione dell'intera immagine.
I livelli di compressione sono normalmente definiti come numeri compresi tra 0 (nessuno) e 9 (migliore). Si riferiscono a compromessi tra velocità e dimensioni e si riferiscono a quante combinazioni di filtri di riga devono essere provate. Non ci sono standard per quanto riguarda questi livelli di compressione, quindi ogni editor di immagini può avere i suoi algoritmi su quanti filtri provare quando si ottimizza la dimensione dell'immagine.
Il livello di compressione 0 significa che i filtri non vengono utilizzati affatto, il che è veloce ma dispendioso. Livelli più alti indicano che vengono provate sempre più combinazioni su file di immagini e vengono conservate solo le migliori.
Immagino che l'approccio più semplice alla migliore compressione sia testare in modo incrementale ogni riga con ciascun filtro, salvare il risultato più piccolo e ripetere per la riga successiva. Ciò equivale a filtrare e comprimere l'intera immagine cinque volte, il che può essere un ragionevole compromesso per un'immagine che verrà trasmessa e decodificata più volte. Valori di compressione inferiori faranno di meno, a discrezione dello sviluppatore dello strumento.
Oltre ai filtri, il livello di compressione potrebbe influire anche sul livello di compressione zlib, che è un numero compreso tra 0 (no Deflate) e 9 (massimo Deflate). Il modo in cui i livelli 0-9 specificati influiscono sull'utilizzo dei filtri, che sono la principale funzione di ottimizzazione di PNG, dipende ancora dallo sviluppatore dello strumento.
La conclusione è che PNG ha un parametro di compressione che può ridurre le dimensioni del file in modo molto significativo, il tutto senza la perdita anche di un singolo pixel.
fonti:
Documentazione libpng di Wikipedia Portable Network Graphics
Capitolo 9 - Compressione e filtro