Bitmap
Una bitmap (BMP) è essenzialmente ciò che descrivi, una matrice di numeri che rappresentano i colori dei pixel. Ad esempio qualcosa del genere
1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1
Compressione senza perdita
Ora definiamo uno schema di compressione. Nel nostro schema di compressione, avremo una matrice di coppie di numeri. Per esempio
3, 1, 1, 0, 7, 1
Ora, la prima cosa che voglio sottolineare è che questo schema di compressione rappresenta gli stessi pixel del primo array. Il primo array ha tre 1 seguiti da un singolo 0 e quindi da sette 1. Ed è quello che rappresentiamo qui. Questo formato è più breve, in quanto rappresenta più pixel con due numeri. Il formato bitmap deve utilizzare un numero per ciascun pixel.
Ovviamente questa è una visione in qualche modo semplificata di un'immagine (ad esempio è solo una riga) e uno schema di compressione. Ma spero che questo ti permetta di vedere come uno schema di compressione cambia il formato di un'immagine. Ecco come si riferisce una GIF a un BMP. GIF utilizza uno schema di compressione chiamato Lempel-Ziv-Welch invece di questo semplicistico.
Quello che abbiamo descritto qui è uno schema di compressione senza perdite. Un problema con gli schemi di compressione senza perdita di dati è che per alcuni input, la forma codificata potrebbe essere più lunga dell'originale. Ad esempio per
1, 0, 1, 0, 1
La codifica è
1, 1, 1, 0, 1, 1, 1, 0, 1, 1
Bene, era inutile. Abbiamo inserito il doppio del tempo.
Un'altra compressione senza perdita
Consideriamo ora un diverso schema di compressione. In questo, rappresenteremo l'immagine come cerchi sovrapposti. Per ogni cerchio, definiremo un centro, un raggio e un colore.
La nostra prima bitmap sarebbe diventata
5, 5, 1, 3, 0, 0
Questa è la stessa lunghezza del nostro primo metodo di compressione.
E il nostro secondo potrebbe essere neanche
2, 2, 1, 2, 1, 0, 2, 0, 1
Si tratta di tre cerchi centrati sull'elemento centrale (che nel conteggio dei computer è il numero 2, poiché i computer iniziano a contare su 0). Un cerchio ha raggio 2 e colore 1. Quindi aggiungiamo un cerchio di colore 0 e raggio 1. Infine, abbiamo un cerchio di colore 1 e raggio 0. A passi, questo sarebbe
1, 1, 1, 1, 1
1, 0, 0, 0, 1
1, 0, 1, 0, 1
O
2, 2, 1, 1, 0, 0, 3, 0, 0
Questo è lo stesso cerchio iniziale ma coperto da due cerchi di punti. A passi sarebbe
1, 1, 1, 1, 1
1, 0, 1, 1, 1
1, 0, 1, 0, 1
Questi sono entrambi uno più corto della prima versione codificata ma ancora più lungo dell'originale.
Potresti chiederti perché sto parlando di cerchi e non di intervalli. Il motivo principale è che i cerchi sono più vicini all'utilizzo di immagini bidimensionali reali.
Compressione in perdita
Abbiamo anche il concetto di schemi di compressione con perdita. Questi schemi di compressione senza perdita di dati possono essere ripristinati nell'array bitmap originale. Gli schemi di compressione con perdita di dati potrebbero non essere reversibili.
Consideriamo una versione con perdita del nostro metodo cerchie. In questo, useremo una semplice regola. Non memorizzeremo alcun cerchio con un raggio inferiore a 1. Quindi, nelle nostre ultime due codifiche, avremmo invece
2, 2, 1, 2, 1, 0
e
2, 2, 1
che sono nuovamente convertiti in pixel
1, 0, 0, 0, 1
e
1, 1, 1, 1, 1
La prima versione è solo un elemento più lungo dell'originale. La seconda versione è più breve. Entrambi sono validi, quindi l'algoritmo è libero di svilupparli entrambi e scegliere quello più corto.
Descriviamo le immagini con regole più restrittive come di qualità inferiore.
Questa rappresentazione di immagini come raccolte sovrapposte di forme circolari è simile al modo in cui funziona il gruppo di esperti fotografici congiunti o il formato JPEG . Le sue forme sono ellissi piuttosto che cerchi, ma l'idea è simile. Piuttosto che il nostro metodo semplicistico, utilizza la trasformazione del coseno discreto per codificare le immagini.
A differenza di GIF, JPEG è in realtà un modo diverso di rappresentare l'immagine. GIF è ancora pixel. Sono semplicemente memorizzati in un modo diverso. JPEG è forme. Per visualizzare un JPEG, convertiamo quindi le forme in pixel perché è così che funzionano gli schermi. In teoria, potremmo sviluppare uno schermo che non ha funzionato in questo modo. Invece di pixel, potrebbe produrre forme in modo da abbinare meglio il formato JPEG. Ovviamente, quello schermo non sarebbe in grado di mostrare bitmap. Per visualizzare un BMP o GIF, dovremmo convertire in JPEG.
Se converti una GIF standard, ad esempio 300x300 pixel, la converti in un JPEG e accendi la qualità fino in fondo, le forme di base che usa dovrebbero essere visibili. Molti JPEG evitano questi artefatti iniziando con un'immagine a risoluzione molto più elevata.
I JPEG si ridimensionano bene perché sono forme piuttosto che pixel. Quindi, se inizi con un'immagine 8000x8000, la converti in JPEG e la visualizzi come immagine 300x300, gran parte dei dettagli persi sarebbero comunque andati persi. Se hai convertito prima la bitmap 8000x8000 in una bitmap 300x300 e poi in JPEG, i risultati saranno spesso di qualità inferiore.
MPEG
Abbiamo parlato di immagini fisse. Il formato Moving Picture Experts Group o MPEG utilizza lo stesso tipo di compressione di JPEG, ma fa anche qualcos'altro. Mentre un modo semplice di fare video è inviare una sequenza di immagini fisse, MPEG in realtà invia un fotogramma, seguito da un certo numero di fotogrammi che elencano le modifiche e finiscono con un fotogramma finale. Poiché la maggior parte dei frame è simile al frame precedente, l'elenco delle modifiche è spesso più piccolo di una seconda immagine.
La sequenza normalmente non è così lunga, diciamo cinque fotogrammi. Ma aiuta a rendere lo stream più piccolo di quanto sarebbe altrimenti.
semplificazioni
Ho ignorato molto. Le mie immagini hanno solo due colori (1 bit), non i 256 di un'immagine a 8 bit e certamente non i 4.294.967.296 di un'immagine a 32 bit. Anche con immagini a 8 bit, tieni presente che spesso puoi scegliere diverse tavolozze per l'immagine. Quindi due bitmap a 8 bit con le stesse sequenze possono rappresentare immagini che sembrano diverse (stessa forma ma colori diversi).
Le mie immagini sono file singole, non bidimensionali. La maggior parte delle immagini avrà una dimensione di riga specifica memorizzata, rendendo le matrici bidimensionali.
Non ho provato a rappresentare le codifiche effettive. Sono molto più complessi di quelli che ho usato. L'ho fatto perché volevo essere in grado di descrivere le codifiche in questo post. Non sono convinto di poter spiegare Lempel-Ziv tanto meno la più complessa raffinatezza di Lempel-Ziv-Welch in un'unica risposta. E non capisco le trasformazioni di Fourier abbastanza bene da spiegarle a lungo.
Questa è davvero una versione semplificata della gestione effettiva delle immagini. Tuttavia, ritengo che ai fini didattici sia più facile da comprendere rispetto alla realtà più complessa, pur continuando a colpire i punti essenziali.