In che modo PNG è senza perdita dato che ha un parametro di compressione?


157

Si dice che i file PNG utilizzino la compressione senza perdita. Tuttavia, ogni volta che mi trovo in un editor di immagini, come GIMP e provo a salvare un'immagine come file PNG, chiede il parametro di compressione, che varia tra 0 e 9. Se ha un parametro di compressione che influenza la precisione visiva di l'immagine compressa, come fa PNG senza perdita di dati?

Ottengo un comportamento senza perdita solo quando imposto il parametro di compressione su 9?


40
La maggior parte degli algoritmi di compressione senza perdita di dati ha parametri sintonizzabili (come le dimensioni del dizionario) che sono generalizzati in un dispositivo di scorrimento "quanto sforzo dovrebbe essere fatto per ridurre al minimo le dimensioni dell'output". Questo è valido per ZIP, GZip, BZip2, LZMA, ...
Daniel B,

20
La domanda potrebbe essere formulata diversamente. Se dalla compressione non viene persa la qualità, perché non utilizzare sempre la compressione producendo le dimensioni più piccole? La risposta sarebbe quindi, perché richiede più RAM e più tempo CPU per comprimere e decomprimere. A volte vuoi una compressione più veloce e non ti interessa tanto del rapporto di compressione.
Kasperd,

14
La compressione PNG è quasi identica ai file ZIPping. È possibile comprimerli più o meno ma si ottiene il file esatto quando si decomprime - questo è ciò che lo rende senza perdite.
mikebabcock,

13
La maggior parte dei software di compressione come Zip e Rar consente di inserire il "livello di compressione" che consente di scegliere tra file più piccoli <--> tempo più breve. Non significa che questi software eliminano i dati durante la compressione. Questa impostazione (in GIMP, pngcrush, ecc.) È simile.
Salman A

2
@naxa: Non ci sono avvertimenti su quanto sia davvero senza perdita di png. È sempre senza perdite al 100%. L'articolo ti avverte solo dei bug che alcuni vecchi browser avevano nella loro implementazione PNG per gestire la correzione gamma. E questo è significativo solo se devi abbinare il colore ai colori CSS (che non sono corretti dalla gamma).
Pauli L

Risposte:


184

PNG è senza perdita di dati. Molto probabilmente GIMP non sta usando la parola migliore in questo caso. Pensalo come "qualità della compressione" o, in altre parole, "livello di compressione". Con una compressione inferiore, si ottiene un file più grande, ma ci vuole meno tempo per produrlo, mentre con una compressione maggiore, si ottiene un file più piccolo che impiega più tempo a produrre. In genere si ottengono rendimenti decrescenti (vale a dire, non tanto diminuzione delle dimensioni rispetto all'aumento del tempo necessario) quando si sale ai massimi livelli di compressione, ma dipende da te.


42
Inoltre, la compressione PNG in realtà ha molti parametri sintonizzabili in cui le regolazioni in entrambe le direzioni possono ridurre le dimensioni dell'output a seconda del contenuto della sorgente: è molto più complessa di un semplice cursore "migliore" e "peggiore". Per scopi generali, non è troppo importante, ma se si desidera il più piccolo assoluto, utilizzare uno strumento del genere in pngcrushgrado di confrontare molte varianti per il più piccolo possibile.
Bob,

4
Un livello di compressione più elevato aumenta il tempo di compressione, ma influisce anche sulla decompressione ?
Nolonar,

10
@Nolonar Generalmente no; semmai un livello di compressione più elevato di solito riduce il tempo di decompressione perché ci sono meno dati da leggere ed elaborare. Il tempo di compressione più lungo è dovuto a un lavoro più approfondito nella ricerca di schemi da comprimere (semplificazione eccessiva).
soffice

1
@fluffy La risposta di LordNeckbeard ha richiesto che la compressione più alta richiedesse 5 volte più tempo per decodificare rispetto alla più bassa.
André Chalella,

1
Per PNG, è abbastanza comune avere un tempo di decompressione più lungo per i file meglio compressi. Il problema è che con PNG, un possibile trucco è applicare l'algoritmo di compressione più e più volte finché il file diventa più piccolo. Una volta che la dimensione aumenta, smetti di applicarla. Quindi è abbastanza possibile applicare l'algoritmo di compressione 5 o 6 volte, il che significa che devi decomprimere il file 5 o 6 volte per visualizzare l'immagine.
yo

213

PNG è compresso, ma senza perdita di dati

Il livello di compressione è un compromesso tra dimensione del file e velocità di codifica / decodifica. Per generalizzare eccessivamente, anche i formati non di immagine, come FLAC, hanno concetti simili.

Diversi livelli di compressione, stesso output decodificato

Sebbene le dimensioni del file siano diverse, a causa dei diversi livelli di compressione, l'output decodificato effettivo sarà identico.

È possibile confrontare gli hash MD5 delle uscite decodificate con l' ffmpegutilizzo del muxer MD5 .

Questo è meglio mostrato con alcuni esempi:

Crea file PNG:

$ ffmpeg -i input -vframes 1 -compression_level 0 0.png
$ ffmpeg -i input -vframes 1 -compression_level 100 100.png
  • Per impostazione predefinita ffmpegverrà utilizzato -compression_level 100per l'output PNG.

Confronta dimensioni file:

$ du -h *.png
  228K    0.png
  4.0K    100.png

Decodifica i file PNG e mostra gli hash MD5:

$ ffmpeg -loglevel error -i 0.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

$ ffmpeg -loglevel error -i 100.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

Poiché entrambi gli hash sono uguali, si può essere certi che le uscite decodificate (il video non compresso e non elaborato) sono esattamente le stesse.


26
+1 non sapeva che ffmpeg poteva gestire i png.
Lekensteyn,

21
@Lekensteyn È fantastico per fare screenshot . Esempio per saltare 30 secondi e fare screenshot: ffmpeg -ss 30 -i input -vframes 1 output.pngBuono anche per realizzare video con immagini e viceversa.
Llogan,

Significa che il PNG deve essere decompresso ogni volta che deve essere reso? Perché se questo è vero, dobbiamo esserlo
akshay2000,

Se rileggi il file dal disco o dalla cache, sì, deve essere decompresso. All'interno della stessa pagina, tuttavia, la cache può probabilmente riutilizzare la versione decompressa.
David Mårtensson,

1
@ akshay2000 Dipende da come funziona il programma che esegue il rendering del PNG. Di solito il file viene letto dal disco, decompresso e bufferizzato nella RAM. Quindi finché è bufferizzato nella RAM non sarà necessario decomprimere nuovamente l'immagine.
xZise,

24

La compressione PNG avviene in due fasi.

  1. La pre-compressione ridispone i dati dell'immagine in modo che siano più comprimibili da un algoritmo di compressione generico.
  2. La compressione effettiva viene eseguita da DEFLATE, che cerca ed elimina sequenze di byte duplicate sostituendole con token brevi.

Poiché il passaggio 2 è un'attività che richiede molto tempo / risorse, la libreria zlib sottostante (incapsulamento del DEFLATE grezzo) accetta un parametro di compressione compreso tra 1 = compressione più veloce, 9 = compressione migliore, 0 = nessuna compressione. Ecco da dove viene l'intervallo 0-9 e GIMP passa semplicemente quel parametro a zlib. Nota che a livello 0 il tuo png sarà in realtà leggermente più grande della bitmap equivalente.

Tuttavia, il livello 9 è solo il "migliore" che tenterà zlib ed è ancora una soluzione di compromesso .
Per avere davvero un'idea di questo, se sei disposto a spendere 1000 volte più potenza di elaborazione in una ricerca esaustiva, puoi ottenere una densità di dati maggiore del 3-8% usando zopfli invece di zlib.
La compressione è ancora senza perdita, è solo una rappresentazione DEFLATE più ottimale dei dati. Questo si avvicina ai limiti di una libreria compatibile con zlib ed è quindi la vera "migliore" compressione che è possibile ottenere usando PNG.


2
Nota: il tempo di decompressione è lo stesso indipendentemente dal livello di compressione o dal conteggio dell'iterazione quando si utilizza zopflipng.
Adria,

16

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:

  1. Pre-compressione: filtro (previsione)
  2. 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:

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


1
Non credo che l'impostazione del livello di compressione cambi l'uso dei filtri. L'impostazione del livello 1-9 probabilmente sceglie solo il livello di compressione zlib 1-9 e il livello 0 significa che l'algoritmo di deflazione non viene utilizzato affatto. La maggior parte delle implementazioni probabilmente non modifica i filtri per riga, ma utilizza sempre il filtro Path sempre.
Pauli L

@PauliL: Non sono d'accordo, perché in tutti i confronti del software di compressione PNG, ci sono differenze molto grandi tra le dimensioni delle immagini generate. Se tutti i prodotti utilizzavano gli stessi parametri per la stessa libreria, tutte le dimensioni avrebbero dovuto essere le stesse e la velocità.
harrymc,

Hai collegamenti a tali confronti?
Pauli L

@PauliL: una rapida ricerca ha portato a questo confronto .
harrymc,

@PauliL: Probabilmente hai ragione sul fatto che i livelli di compressione di zlib sono influenzati dai livelli di compressione di PNG. Ho modificato la mia risposta di conseguenza, anche se nessuno strumento di compressione documenta esattamente cosa fanno. Forse la spiegazione per gli strumenti con risultati di dimensioni peggiori è che non usano affatto filtri, solo compressione zlib.
harrymc,

5

OK, sono troppo tardi per la generosità, ma ecco comunque la mia risposta.

PNG è sempre senza perdite . Utilizza l'algoritmo Deflate / Inflate, simile a quelli utilizzati nei programmi zip.

L'algoritmo Deflate cerca sequenze ripetute di byte e sostituisce quelle con tag. L'impostazione del livello di compressione specifica la quantità di sforzo che il programma impiega per trovare la combinazione ottimale di sequenze di byte e la quantità di memoria riservata a questo. È un compromesso tra tempo e utilizzo della memoria rispetto alle dimensioni del file compresso. Tuttavia, i computer moderni sono così veloci e dispongono di memoria sufficiente per cui raramente è necessario utilizzare impostazioni diverse dalla massima compressione.

Molte implementazioni PNG usano la libreria zlib per la compressione. Zlib ha nove livelli di compressione, 1-9. Non conosco gli interni di Gimp, ma dal momento che ha impostazioni del livello di compressione 0-9 (0 = nessuna compressione), suppongo che questa impostazione selezioni semplicemente il livello di compressione di zlib.

L'algoritmo Deflate è un algoritmo di compressione generico , non è stato progettato per la compressione di immagini. A differenza della maggior parte degli altri formati di file di immagini senza perdita di dati, il formato PNG non si limita a questo. La compressione PNG sfrutta la consapevolezza che stiamo comprimendo un'immagine 2D . Ciò è ottenuto dai cosiddetti filtri .

(Filtro in realtà è un termine un po 'fuorviante qui. In realtà non cambia il contenuto dell'immagine, ma semplicemente lo codifica in modo diverso. Un nome più preciso sarebbe delta encoder.)

La specifica PNG specifica 5 filtri diversi (incluso 0 = nessuno). Il filtro sostituisce i valori assoluti dei pixel con la differenza rispetto ai pixel precedenti a sinistra, in alto, in diagonale o in combinazione con quelli. Ciò può migliorare significativamente il rapporto di compressione. Ogni riga di scansione sull'immagine può utilizzare un filtro diverso. L'encoder può ottimizzare la compressione scegliendo il filtro migliore per ogni linea.

Per i dettagli sul formato del file PNG, vedere Specifiche PNG .

Poiché esiste un numero praticamente infinito di combinazioni, non è possibile provarle tutte. Pertanto, sono stati sviluppati diversi tipi di strategie per trovare una combinazione efficace. La maggior parte degli editor di immagini probabilmente non tenta nemmeno di ottimizzare i filtri riga per riga, ma utilizza semplicemente un filtro fisso (molto probabilmente Paeth).

Un programma da riga di comando pngcrush prova diverse strategie per trovare il risultato migliore. Può ridurre significativamente la dimensione del file PNG creato da altri programmi, ma potrebbe richiedere parecchio tempo su immagini più grandi. Vedi Source Forge - pngcrush .


3

Il livello di compressione nelle cose senza perdita è sempre solo il trading di risorse di codifica (di solito tempo, a volte anche RAM) rispetto al bitrate. La qualità è sempre al 100%.

Naturalmente, i compressori lossless non possono MAI garantire alcuna compressione effettiva. I dati casuali sono incomprimibili, non c'è motivo da trovare e nessuna somiglianza. Teoria dell'informazione Shannon e tutto il resto. Il punto centrale della compressione dei dati senza perdita di dati è che gli umani di solito lavorano con dati altamente non casuali, ma per la trasmissione e l'archiviazione, possiamo comprimerli nel minor numero di bit possibile. Speriamo che sia il più vicino possibile alla complessità di Kolmogorov dell'originale.

Che si tratti di dati generici zip o 7z, immagini png, audio flac o video h.264 (in modalità lossless), è la stessa cosa. Con alcuni algoritmi di compressione, come lzma (7zip) e bzip2, aumentare l'impostazione di compressione aumenterà il tempo di CPU del DECODER (bzip2) o più spesso solo la quantità di RAM necessaria (lzma e bzip2 e h.264 con più frame di riferimento) . Spesso il decodificatore deve salvare più output decodificato nella RAM perché la decodifica del byte successivo potrebbe riferirsi a un byte decodificato molti megabyte fa (ad esempio un fotogramma video che è più simile a uno da mezzo secondo fa verrebbe codificato con riferimenti a 12 fotogrammi indietro ). Stessa cosa con bzip2 e la scelta di un blocco di grandi dimensioni, ma anche quello si decomprime più lentamente. lzma ha un dizionario di dimensioni variabili e potresti creare file che richiederebbero 1.


Hmmm ho visto un'implementazione per strappare il controllo del motore passo-passo e della testa direttamente per fornire una compressione senza perdita garantita. La codifica Manchester viene facilmente battuta se si dispone di una sorgente di clock ad alta risoluzione.
Giosuè,

@Joshua: L'uso di un formato di archiviazione fisico ad alta densità non è lo stesso della compressione dei dati ...
SamB

0

Innanzitutto, PNG è sempre senza perdite. L'apparente paradosso è dovuto al fatto che esistono due diversi tipi di compressione (per qualsiasi tipo di dati): lossy e lossless.

La compressione senza perdita comprime i dati (ovvero la dimensione del file) usando vari trucchi, mantenendo tutto e senza fare alcuna approssimazione. Di conseguenza, è possibile che la compressione senza perdita non sia effettivamente in grado di comprimere le cose. (Tecnicamente i dati con elevata entropia possono essere molto difficili o addirittura impossibili da comprimere per metodi senza perdita.) La compressione con perdita si avvicina ai dati reali, ma l'approssimazione è imperfetta, ma questo "lancio" di precisione consente in genere una compressione migliore.

Ecco un esempio banale di compressione senza perdita: se hai un'immagine fatta di 1.000 pixel neri, invece di memorizzare il valore per il nero 1.000 volte, puoi memorizzare un conteggio (1000) e un valore (nero) comprimendo così un 1000 pixel " immagine "in soli due numeri. (Questa è una forma grezza di un metodo di compressione senza perdita di dati chiamato codifica run-length).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.