Come configurare smartphone e PC. Portale informativo
  • casa
  • Windows 7, XP
  • Implementa la compressione delle immagini usando jpeg c. JPEG, JPEG2000, JPEG-LS

Implementa la compressione delle immagini usando jpeg c. JPEG, JPEG2000, JPEG-LS

Le foto e le immagini differiscono l'una dall'altra non solo nel contenuto, ma anche in altre caratteristiche del "computer". Ad esempio, nelle dimensioni.

Succede che, tipo, due modelli identici, ma una dimensione è tre volte più grande dell'altra.

Inoltre, le immagini differiscono in termini di qualità. Penso che tu abbia visto foto di qualità estremamente scadente più di una volta. Questo può essere visto ad occhio nudo. Ad esempio, due foto identiche, ma una della migliore qualità e l'altra della peggiore.

E succede che l'immagine sembra mancare di colori. Ecco un esempio.

E il formato o il tipo di file è responsabile di tutto questo.

In effetti, le immagini sono le più diversi formati... E ci sono un sacco di loro. Non li considereremo tutti, ma parleremo di quelli più comuni. Questi sono formati come bmp, gif, jpg, png, tiff.

Differiscono l'uno dall'altro, prima di tutto, nella qualità. E la qualità differisce nel numero (saturazione) dei colori.

Ad esempio, dipingo un quadro utilizzando colori diversi. E poi improvvisamente alcuni di loro sono finiti, e devi finire di dipingere con quello che abbiamo. Certo, cercherò di fare tutto il possibile in modo che ciò non influenzi molto il risultato, ma comunque l'immagine non risulterà come vorrei: più sbiadita, sfocata.

Così è con i formati di immagine. Uno lascia tutti i colori, l'altro ne taglia una parte. E, succede, a causa di ciò, l'immagine si deteriora.

Questo è un esempio piuttosto grezzo. In effetti, lì è tutto un po' più complicato, ma penso che tu abbia colto la cosa principale.

Formati immagine comuni

BMP è un formato per i disegni realizzati in Paint. Può essere utilizzato per memorizzare le immagini disegnate sul computer. Ma questo tipo di file non viene utilizzato su Internet a causa delle sue grandi dimensioni. Quindi, se vuoi pubblicare un'immagine disegnata in Paint, su un blog o un social network, deve essere di un tipo diverso: gif, jpg o png.

GIF è un formato di immagine popolare su Internet. Puoi salvarli senza perdere qualità, ma con numero limitato colori - 256. La GIF ha guadagnato particolare popolarità grazie al fatto che in essa è possibile creare piccole immagini animate (in movimento).

JPG è un formato di foto e immagini con molti colori. Può salvare un'immagine sia senza perdita di qualità che con perdita.

PNG è un formato moderno per le immagini. Questo tipo di immagine non si ottiene. grande taglia e senza perdita di qualità. Molto comodo: il file è piccolo e la qualità è buona. Supporta anche la trasparenza.

TIFF: immagini di ottima qualità, non compresse e, di conseguenza, la dimensione di tali file è enorme. TIFF viene utilizzato quando la qualità è Grande importanza... Ad esempio, quando si creano biglietti da visita, brochure, copertine di riviste.

Quale formato scegliere

  • BMP - se questo è un disegno realizzato in Paint e lo conserverai solo nel computer.
  • GIF - se un'animazione o un disegno con una piccola quantità di colori per la pubblicazione su Internet.
  • PNG - se è un disegno con molti colori o alcune parti trasparenti.
  • JPG (jpeg) - se foto.
  • TIFF - un'immagine per la stampa (biglietti da visita, brochure, poster, ecc.).

Ciao cari amici. Oggi parleremo di quale formato di immagine è meglio utilizzare sul sito, quali formati di file grafici sono disponibili oggi per il sito e se è necessario inseguire gli ultimi formati grafici.

Ricevo molte di queste domande, molti dei miei studenti chiedono se possono utilizzare i nuovi formati SVG e WebP e dove è meglio applicare queste immagini. Certo, puoi anche usare nuovi formati, ma devi capire quale formato è più adatto per cosa.

Oggi le immagini sul sito ne sono parte integrante. Partendo da disegno grafico e il caricamento di immagini negli articoli, la grafica accompagna la maggior parte dei siti sul web. Ma la bellezza ha un prezzo

Le immagini non ottimizzate sono uno dei fattori di rallentamento del sito web, come indicato dai servizi di verifica.

Pertanto, ti troverai sempre di fronte alla scelta di quale formato scegliere per l'immagine. Le sue dimensioni e qualità dipenderanno da questo. E per utilizzare immagini più piccole senza perdere qualità, ci sono alcune cose che devi sapere.

Quali immagini uso per i siti web oggi?

Tutte le immagini per i siti sono suddivise:

  • raster (esempio: JPG, JPEG, GIF, PNG),
  • vettore (esempio - SVG).

Raster le immagini sono costituite da pixel che memorizzano il valore di colore e trasparenza. Questi formati sono immagini in articoli, pulsanti, icone ed elementi di design. Queste immagini sono popolari tra gli sviluppatori e i proprietari di siti web. Il principale svantaggio delle bitmap è che non si ridimensionano bene.

Cioè, quando si aumenta la dimensione dell'immagine, si verifica una perdita di qualità.

Vettore le immagini sono composte da linee e punti di rotta. Le informazioni su un'immagine sono memorizzate in istruzioni di disegno matematico, che consentono di ridimensionare tali immagini quanto desiderato senza perdita di qualità.

Tutte queste immagini possono e sono utilizzate sui siti Web moderni. Devi solo capirlo prima di caricare sul sito!

Descrizione dei formati di immagine più diffusi per il sito

Dalla descrizione di questi formati capirai dove e quale formato è meglio utilizzato nel sito.

JPEG

JPEG o JPG è uno dei formati di immagine più popolari per i siti Web. Il formato supporta milioni di colori, il che gli conferisce una posizione di primo piano nella presentazione di foto e immagini sul sito.

Le immagini in questo formato sono ottimizzate abbastanza bene con quasi nessuna perdita di qualità, il che consente di ottenere un file più piccolo senza perdita di qualità visiva. Va ricordato che ogni successiva ottimizzazione diminuisce la qualità.

I file di questo formato sono supportati da tutti i dispositivi e browser, il che conferma ancora una volta la sua popolarità e ti consente di non preoccuparti dei problemi di visualizzazione sui siti.

Il grande svantaggio di questo formato è la mancanza di trasparenza. Cioè, non funzionerà per combinare le immagini in questo formato. Per tali attività, è meglio utilizzare il seguente formato.

Immagine PNG

Questo formato utilizza un algoritmo di compressione senza perdita di dati. In termini di numero di colori e livello di trasparenza, è disponibile in due tipologie, 8 e 24 bit. Entrambi supportano la trasparenza.

8 bit non è molto popolare, ma 24 bit è ampiamente utilizzato per varie immagini sul sito. Grazie alla trasparenza, consente di creare immagini combinate. Viene spesso utilizzato per creare pulsanti animati, icone, dove è necessario un effetto di trasparenza.

Le immagini PNG possono essere ottimizzate molte volte, modificate - manterranno la qualità originale.

Il formato è inoltre supportato da tutti i browser e dispositivi per garantire che venga visualizzato su qualsiasi schermo.

La qualità delle immagini sembra migliore di JPG, ma il peso del file sarà maggiore. Questo deve essere preso in considerazione quando si posizionano i file sul sito.

GIF

È un formato a 8 bit che supporta 256 colori, trasparenza e animazione. A causa del supporto di un numero ridotto di colori, anche il peso del file è minimo.

Il formato non è adatto per fotografie e immagini con vasta gamma colori.

Ma è ampiamente utilizzato durante la creazione di banner, pulsanti, icone e così via.

Questo formato viene utilizzato sempre meno nei siti Web moderni.

Successivamente, parliamo dei formati SVG e WebP relativamente recenti, che non sono così popolari, ma stanno guadagnando popolarità e supporto e sono i più adatti ai requisiti di velocità di caricamento e reattività del sito.

SVG

È un formato di file vettoriale su Basato su XML... Il formato ha iniziato a guadagnare popolarità abbastanza di recente, poiché in precedenza era scarsamente supportato nei browser. E a causa di problemi di visualizzazione, nessuno aveva fretta di usarlo.

Oggi SVG è supportato da tutti i browser moderni. Ma ci sono ancora problemi con il display.

Questo formato è più comunemente usato per immagini semplici come loghi, elementi di design e così via. Non applicabile per le fotografie.

Il formato SVG è leggero, si adatta bene per immagini nitide a qualsiasi risoluzione dello schermo, supporta l'animazione, può essere manipolato tramite CSS e inserito in HTML, riducendo il numero di richieste.

Webp

Formato aperto codice sorgente, sviluppato da Google appositamente per Internet. YouTube oggi utilizza la conversione delle miniature dei video in formato WebP.

Il formato fornisce una compressione superiore e mantiene la trasparenza. Combina i vantaggi dei formati JPG e PNG senza aumentare le dimensioni del file.

Ma nonostante i vantaggi del formato, non è supportato da tutti i browser, come IE, Edge, Firefox e Safari.

Esistono modi per aggirare queste limitazioni, ma impediscono l'utilizzo universale del formato.

Conclusione

Amici, spero di aver spiegato tutto chiaramente, e ora sapete quale formato di immagine è meglio usare sul sito e perché non insisto nell'usare un formato particolare, ma consiglio un approccio integrato.

Forse quando WebP otterrà un ampio supporto, passeremo tutti ad esso e sostituiremo jpg e png sui nostri siti.

Discutiamo nei commenti di quali formati usi sui tuoi siti, cosa ti piace e cosa non ti piace.

Per oggi ho tutto, aspetto i vostri commenti.

Cordiali saluti, Maxim Zaitsev.

    CON I più popolari sono tre formati di file: JPEG, RAW, TIFF. A volte puoi sentire disaccordi tra i fotografi: qual è il miglior formato di file per la fotografia, in quale formato è meglio scattare foto, perché le fotocamere moderne ti consentono di scattare fotostampa in uno di questi formati e talvolta in più formati contemporaneamente!

    Il formato del file in cui è memorizzata l'immagine è, infatti, un certo compromesso tra qualità dell'immagine e dimensione del file.

    Probabilmente sai già che una bitmap è composta da pixel. Come è organizzato un file raster e in quale forma memorizza le informazioni sui pixel e determina il formato del file. La qualità dell'immagine per un file raster è determinata da due parametri principali: la dimensione dei pixel (ovvero il numero totale di pixel) e l'accuratezza della riproduzione effettiva del colore mediante il colore del pixel.Con la dimensione dei pixel è chiaro: più pixel (o - più "piccolo" è il pixel), meglio è.E la precisione del colore dipende dal numero di colori per pixel o dalla profondità del colore.

    Profondità del colore (qualità del colore, bit dell'immagine) - la quantità di memoria nel numero di bit utilizzati per memorizzare e rappresentare il colore durante la codifica di un pixel grafica bitmap o immagini video. Il numero di bit indica il numero di gradazioni (passi tonali) in ogni componente di colore, o, semplicemente, il numero di colori. L'aggiunta di 1 bit equivale all'aggiunta di un altro bit al codice colore binario.

    • Colore binario a 1 bit (21 = 2 colori), il più delle volte rappresentato da bianco e nero (o nero e verde)
    • Colore a 2 bit (22 = 4 colori) CGA Scala di grigi NeXTstation
    • Colore a 3 bit (23 = 8 colori) molti personal computer legacy con uscita TV
    • Il colore a 4 bit (24 = 16 colori) è noto come EGA e, in misura minore, come standard ad alta risoluzione VGA
    • Colore a 5 bit (25 = 32 colori) Chipset originale Amiga
    • Colore a 6 bit (26 = 64 colori) Chipset originale Amiga
    • Colore a 8 bit (28 = 256 colori) Workstation legacy Unix, VGA a bassa risoluzione, Super VGA, AGA
    • Colore a 12 bit (212 = 4.096 colori) alcuni sistemi Silicon Graphics, sistemi di colore NeXTstation e sistemi in modalità Amiga HAM.

    Ad esempio, stiamo lavorando nello spazio colore RGB. Ciò significa che ci sono tre canali da cui viene formato il colore del pixel finale: il canale rosso (Rad), il canale verde (Green) e il canale blu (Blue). Supponiamo che i canali siano a 4 bit. Ciò significa che ogni canale ha la capacità di visualizzare 16 colori. Di conseguenza, tutto RGB sarà a 12 bit e sarà in grado di visualizzare

    C = 16x16x16 = 4096 colori

    La profondità del colore in questo caso è di 12 bit.

    Quando parliamo di RGB a 24 bit, intendiamo canali a 8 bit (256 colori ciascuno) con un numero totale di opzioni di colore per pixel

    C = 256x256x256 = 16777216 colori.

    La cifra è impressionante. Questo numero di colori per ogni pixel soddisfa le esigenze del fotografo più esigente.

    Un po 'sui formati stessi.

    formato TIFF

    TIFF sta per Tagged Image File Format ed è uno standard per il settore della stampa e della stampa.

    Di conseguenza, risulta così:

    1. Se la tua fotocamera è così semplice da scattare solo JPEG e vuoi ottenere la massima qualità, imposta la dimensione massima e la compressione minima e non tormentarti per il fatto che non hai altri formati. Nella maggior parte dei casi, un'immagine RAW accuratamente realizzata a mano corrisponde a una fotocamera JPEG acquisita automaticamente.

    2. Forse non dovresti fare foto in TIFF. La registrazione in questo formato è più difficile e non ci sono differenze evidenti rispetto al JPEG di alta qualità.

    3. Se hai la possibilità di scattare foto, lavoraci. Sentirai tu stesso se ti si addice. In alcuni casi, solo RAW consente di realizzare una foto unica per un elevato ingrandimento durante la stampa.

    Rimane un'altra soluzione, si potrebbe dire universale. C'è una modalità che ti permette di scattare foto in due formati contemporaneamente: RAW + JPEG. Cattura scene importanti in questa modalità. I moderni archivi di informazioni digitali, sia schede di memoria che dischi rigidi, ti consentono di farlo. In questo caso, ottieni un JPEG per utilizzare immediatamente la foto, senza perdere tempo per la revisione. E, se ne hai bisogno, affida il file RAW a uno specialista per l'elaborazione.

    La foto. Formati di file.

    È facile calcolare che un'immagine a colori non compressa di 2000 * 1000 pixel avrà una dimensione di circa 6 megabyte. Se parliamo di immagini ottenute da fotocamere o scanner professionali alta risoluzione, quindi la loro dimensione può essere anche maggiore. Nonostante la rapida crescita della capacità di archiviazione, vari algoritmi di compressione delle immagini sono ancora molto rilevanti.
    Tutti gli algoritmi esistenti possono essere suddivisi in due grandi classi:

    • Algoritmi di compressione senza perdite;
    • Algoritmi di compressione con perdita.
    Quando parliamo di compressione senza perdita di dati, intendiamo che esiste un algoritmo che è l'opposto dell'algoritmo di compressione, che consente di ripristinare con precisione l'immagine originale. Non esiste un algoritmo inverso per gli algoritmi di compressione con perdita. Esiste un algoritmo che ripristina un'immagine che non corrisponde necessariamente esattamente a quella originale. Gli algoritmi di compressione e recupero sono selezionati per ottenere un elevato rapporto di compressione mantenendo la qualità visiva dell'immagine.

    Algoritmi di compressione senza perdite

    Algoritmo RLE
    Tutti gli algoritmi serie RLE si basano su un'idea molto semplice: gruppi ripetuti di elementi vengono sostituiti da una coppia (numero di ripetizioni, elemento ripetuto). Consideriamo questo algoritmo usando una sequenza di bit come esempio. In questa sequenza si alterneranno gruppi di zero e uno. Inoltre, i gruppi avranno spesso più di un elemento. Quindi la sequenza 11111 000000 11111111 00 corrisponderà alla seguente serie di numeri 5 6 8 2. Questi numeri indicano il numero di ripetizioni (il conteggio inizia da uno), ma anche questi numeri devono essere codificati. Supponiamo che il numero di ripetizioni sia compreso tra 0 e 7 (cioè 3 bit sono sufficienti per codificare il numero di ripetizioni). Quindi la sequenza considerata sopra è codificata dalla seguente sequenza di numeri 5 6 7 0 1 2. È facile calcolare che sono necessari 21 bit per codificare la sequenza originale, e nella sequenza compressa Metodo RLE questa sequenza richiede 18 bit.
    Sebbene questo algoritmo sia molto semplice, la sua efficacia è relativamente bassa. Inoltre, in alcuni casi, l'uso di questo algoritmo porta non ad una diminuzione, ma ad un aumento della lunghezza della sequenza. Ad esempio, si consideri la seguente sequenza 111 0000 11111111 00. La sequenza RL corrispondente ha questo aspetto: 3 4 7 0 1 2. La lunghezza della sequenza originale è di 17 bit, la lunghezza della sequenza compressa è di 18 bit.
    Questo algoritmo è più efficace per le immagini in bianco e nero. Viene spesso utilizzato anche come uno degli stadi intermedi di compressione di algoritmi più complessi.

    Algoritmi del dizionario

    L'idea alla base degli algoritmi del dizionario è che le stringhe di elementi nella sequenza originale sono codificate. In questa codifica viene utilizzato un dizionario speciale, ottenuto dalla sequenza originale.
    Esiste un'intera famiglia di algoritmi di vocabolario, ma esamineremo l'algoritmo LZW più comune, che prende il nome dai suoi sviluppatori Lepel, Ziv e Welch.
    Il dizionario in questo algoritmo è una tabella che viene riempita con stringhe di codifica durante l'esecuzione dell'algoritmo. Durante la decodifica del codice compresso, il dizionario viene ripristinato automaticamente, quindi non è necessario trasferire il dizionario insieme al codice compresso.
    Il dizionario è inizializzato con tutte le stringhe singleton, ad es. le prime righe del dizionario rappresentano l'alfabeto in cui stiamo codificando. La compressione cerca la catena più lunga già scritta nel dizionario. Ogni volta che si incontra una stringa che non è stata ancora scritta nel dizionario, viene aggiunta lì e viene emesso un codice compresso corrispondente alla stringa già scritta nel dizionario. In teoria, non vengono imposte restrizioni alla dimensione del dizionario, ma in pratica ha senso limitare questa dimensione, poiché nel tempo iniziano a verificarsi catene che non si trovano più nel testo. Inoltre, quando la dimensione della tabella viene raddoppiata, dobbiamo allocare un bit in più per memorizzare i codici compressi. Per evitare tali situazioni, viene introdotto un codice speciale che simboleggia l'inizializzazione della tabella da parte di tutte le stringhe singleton.
    Consideriamo un esempio di compressione da parte dell'algoritmo. Stringeremo la corda del cuculo, il cuculo, il cuculo ha comprato il cappuccio. Supponiamo che il dizionario contenga 32 posizioni, il che significa che ciascuno dei suoi codici occuperà 5 bit. Inizialmente, il dizionario è compilato come segue:

    Questa tabella è, sia dalla parte di chi comprime le informazioni, sia dalla parte di chi disimballa. Ora esamineremo il processo di compressione.


    La tabella mostra il processo di compilazione del dizionario. È facile calcolare che il codice compresso risultante richiede 105 bit e il testo originale (assumendo che si spendano 4 bit per codificare un carattere) richiede 116 bit.
    In effetti, il processo di decodifica si riduce alla decifratura diretta dei codici, mentre è importante che la tabella venga inizializzata allo stesso modo della codifica. Ora diamo un'occhiata all'algoritmo di decodifica.



    Possiamo definire completamente la stringa aggiunta al dizionario al passaggio i-esimo solo a i + 1. Ovviamente la i-esima riga deve terminare con il primo carattere i + 1 della riga. Quella. abbiamo appena capito come ripristinare un dizionario. Di un certo interesse è la situazione in cui viene codificata una sequenza della forma cScSc, dove c è un carattere e S è una stringa e la parola cS è già nel dizionario. A prima vista può sembrare che il decoder non sia in grado di risolvere questa situazione, ma in realtà tutte le linee di questo tipo devono terminare sempre con lo stesso carattere con cui iniziano.

    Algoritmi di codifica entropia
    Gli algoritmi di questa serie assegnano il codice compresso più breve agli elementi di sequenza più frequenti. Quelli. sequenze della stessa lunghezza sono codificate con codici compressi di lunghezze diverse. Inoltre, più spesso si verifica la sequenza, più breve è il codice compresso corrispondente.
    Algoritmo di Huffman
    L'algoritmo di Huffman ti consente di creare codici di prefisso. Puoi pensare ai codici di prefisso come percorsi su un albero binario: il passaggio da un nodo al suo figlio sinistro corrisponde a 0 nel codice, e al suo figlio destro - 1. Se contrassegniamo le foglie dell'albero con caratteri codificati, ottenere la rappresentazione codice prefisso come albero binario.
    Descriviamo un algoritmo per costruire un albero di Huffman e ottenere codici di Huffman.
  1. I caratteri nell'alfabeto di input formano un elenco di nodi liberi. Ogni foglio ha un peso pari alla frequenza di occorrenza del simbolo
  2. Vengono selezionati due nodi liberi dell'albero con i pesi minori
  3. Il loro genitore viene creato con un peso pari al loro peso totale
  4. Il genitore viene aggiunto all'elenco dei nodi liberi e i suoi due figli vengono rimossi da questo elenco
  5. Ad un arco che esce dal genitore viene assegnato il bit 1, l'altro - bit 0
  6. I passaggi a partire dal secondo vengono ripetuti fino a quando nella lista libera rimane un solo nodo libero. Sarà considerato la radice dell'albero.
Usando questo algoritmo, possiamo ottenere i codici di Huffman per un dato alfabeto, tenendo conto della frequenza di occorrenza dei caratteri.
Codifica aritmetica
Gli algoritmi di codifica aritmetica codificano stringhe di elementi in frazioni. Ciò tiene conto della distribuzione di frequenza degli elementi. Al momento, gli algoritmi di codifica aritmetica sono protetti da brevetti, quindi considereremo solo l'idea di base.
  • Tutorial

UPD. È stato costretto a rimuovere la formattazione a spaziatura fissa. Un bel giorno, l'habraparser ha smesso di percepire la formattazione all'interno dei tag pre e code. L'intero testo si è trasformato in un pasticcio. L'amministrazione Habr non ha potuto aiutarmi. Ora irregolare, ma almeno leggibile.

Ti sei mai chiesto come funziona un file jpg? Scopriamolo ora! Riscalda il tuo compilatore preferito e l'editor esadecimale, decodifichiamo questo:

Ho appositamente preso un disegno più piccolo. Questa è la favicon di Google familiare ma fortemente compressa:

Ti avverto subito che la descrizione è semplificata, e le informazioni fornite non sono complete, ma in seguito sarà facile capire la specifica.

Senza nemmeno sapere come avviene la codifica, possiamo già estrarre qualcosa dal file.
- inizio marcatore. Si trova sempre all'inizio di tutti i file jpg.
Seguito da byte ... Questo è un marcatore che segna l'inizio della sezione dei commenti. Prossimi 2 byte - la lunghezza della sezione (compresi questi 2 byte). Quindi nei prossimi due - il commento stesso. Questi sono i codici per i caratteri ":" e ")", ad es. emoticon normale. Puoi vederlo sulla prima riga del lato destro dell'editor esadecimale.

Un po' di teoria

Molto brevemente in passi:
Pensiamo all'ordine in cui questi dati possono essere codificati. Supponiamo, prima, completamente, per l'intera immagine, che sia codificato il canale Y, quindi Cb, quindi Cr. Tutti ricordano di aver caricato le immagini sul dial-up. Se fossero codificati in questo modo, dovremmo aspettare che l'intera immagine venga caricata prima che appaia sullo schermo. Sarà anche spiacevole se la fine del file viene persa. Probabilmente ci sono anche altre buone ragioni. Pertanto, i dati codificati sono disposti alternativamente, in piccole parti.

Vi ricordo che ogni blocco Y ij, Cb ij, Cr ij è una matrice di coefficienti DCT codificati con codici di Huffman. Nel file sono disposti nel seguente ordine: Y 00 Y 10 Y 01 Y 11 Cb 00 Cr 00 Y 20

Lettura di un file

Dopo aver estratto il commento, dovrebbe essere facile capire che:
  • Il file è suddiviso in settori preceduti da marker.
  • I marker sono lunghi 2 byte, con il primo byte.
  • Quasi tutti i settori memorizzano la loro lunghezza nei 2 byte successivi al marker.
Per comodità, evidenziamo i marker:
FF D8 FF FE 00 04 3A 29 FF DB 00 43 00 A0 6E 78



FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 00
43 01 AA B4 B4 F0 D2 F0 FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF C0 00 11 08 00 10 00 10 03 01 22 00 02
11 01 03 11 01 FF C4 00 15 00 01 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 03 02 FF C4 00 1A
10 01 00 02 03 01 00 00 00 00 00 00 00 00 00 00
00 01 00 12 02 11 31 21 FF C4 00 15 01 01 01 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF
C4 00 16 11 01 01 01 00 00 00 00 00 00 00 00 00
00 00 00 00 11 00 01 FF DA 00 0C 03 01 00 02 11
03 11 00 3F 00 AE E7 61 F2 1B D5 22 85 5D 04 3C
82 C8 48 B1 DC BF FF D9

Marker: DQT - tabella di quantizzazione.

FF DB 00 43 00 A0 6E 78
8C 78 64 A0 8C 82 8C B4 AA A0 BE F0 FF FF F0 DC
DC F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF

L'intestazione della sezione è sempre di 3 byte. Nel nostro caso lo è. L'intestazione è composta da:
Lunghezza: 0x43 = 67 byte
Lunghezza dei valori nella tabella: 0 (0 - 1 byte, 1 - 2 byte)
[_0] ID tabella: 0
I restanti 64 byte devono riempire la tabella 8x8.



Dai un'occhiata più da vicino all'ordine in cui sono riempiti i valori della tabella. Questo ordine è chiamato ordine a zigzag:

Marker: SOF0 - Baseline DCT

Questo marker si chiama SOF0, e significa che l'immagine è codificata dal metodo base. È molto comune. Ma su Internet, non meno popolare è il metodo progressivo che ti è familiare, quando per la prima volta viene caricata un'immagine da Bassa risoluzione, e poi un'immagine normale. Questo ti permette di capire cosa viene mostrato lì senza aspettare un download completo. La specifica definisce alcuni metodi in più, mi sembra, non molto comuni.

FF C0 00 11 08 00 10 00 10 03 01 22 00 02
11 01 03 11 01

Lunghezza: 17 byte.
Precisione: 8 bit. Nel metodo di base, è sempre 8. A quanto ho capito, questa è la profondità di bit dei valori del canale.
Altezza del motivo: 0x10 = 16
Larghezza del motivo: 0x10 = 16
Numero di componenti: 3. Molto spesso si tratta di Y, Cb, Cr.

1° componente:
ID: 1
Diradamento orizzontale (H 1): 2
[_2] Decimazione verticale (V 1): 2
ID tabella di quantizzazione: 0

2° componente:
ID: 2
Diradamento orizzontale (H 2): 1
[_1] Diradamento verticale (V 2): 1

3° componente:
ID: 3
Diradamento orizzontale (H 3): 1
[_1] Diradamento verticale (V 3): 1
ID tabella di quantizzazione: 1

Ora vedi come determinare quanto è sottile l'immagine. Trova H max = 2 e V max = 2. Il canale i sarà tagliato in H max / H i volte orizzontalmente e V max / V i volte verticalmente.

Marker: DHT (tabella di Huffman)

Questa sezione memorizza i codici e i valori ottenuti dalla codifica di Huffman.

FF C4 00 15 00 01 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 03 02

lunghezza: 21 byte.
classe: 0 (0 - tabella coefficienti DC, 1 - tabella coefficienti AC).
[_0] ID tabella: 0
Lunghezza del codice Huffman: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Numero di codici:
Il numero di codici indica il numero di codici di quella lunghezza. Nota che la sezione memorizza solo le lunghezze dei codici, non i codici stessi. Dobbiamo trovare i codici da soli. Quindi, abbiamo un codice di lunghezza 1 e uno - di lunghezza 2. Ci sono 2 codici in totale, non ci sono più codici in questa tabella.
Un valore è associato a ciascun codice e sono elencati di seguito nel file. I valori sono a byte singolo, quindi leggiamo 2 byte.
- il valore del 1° codice.
- il valore del 2° codice.

Costruire un albero del codice di Huffman

Dobbiamo costruire un albero binario dalla tabella che abbiamo ottenuto nella sezione DHT. E già da questo albero riconosciamo ogni codice. Aggiungiamo i valori nell'ordine in cui sono indicati nella tabella. L'algoritmo è semplice: non importa dove siamo, cerchiamo sempre di aggiungere un valore al ramo sinistro. E se è occupata, allora a destra. E se non c'è spazio lì, torniamo a un livello superiore e proviamo da lì. È necessario fermarsi a un livello pari alla lunghezza del codice. I rami di sinistra corrispondono a 0, i rami di destra - 1.
Commento:
Non devi iniziare dall'alto ogni volta. Valore aggiunto: torna indietro di un livello. Esiste il ramo giusto? Se è così, sali di nuovo. In caso contrario, crea il ramo giusto e naviga lì. Quindi, da lì, inizia la tua ricerca per aggiungere il valore successivo.

Alberi per tutte le tabelle in questo esempio:


UPD (grazie): I nodi del primo albero (DC, id = 0) devono avere i valori 0x03 e 0x02

Nei cerchi - i valori dei codici, sotto i cerchi - i codici stessi (spiegherò che li abbiamo ottenuti, andando dall'alto a ciascun nodo). È con tali codici (di questa e di altre tabelle) che viene codificato il contenuto della figura stessa.

Marcatore: SOS (inizio della scansione)

Il byte nel marker significa “SI! Infine, siamo passati direttamente all'analisi della sezione dell'immagine codificata! ". Tuttavia, la sezione è chiamata simbolicamente SOS.

& nbsp FF DA 00 0C 03 01 00 02 11
03 11 00 3F 00

La lunghezza della parte dell'intestazione (non l'intera sezione): 12 byte.
Il numero di componenti di scansione. Abbiamo 3, uno per Y, Cb, Cr.

1° componente:
Numero parte immagine: 1 (Y)
ID tabella Huffman per coefficienti DC: 0
[_0] ID tabella Huffman per coefficienti AC: 0

2° componente:
Numero parte immagine: 2 (Cb)

[_1]

3° componente:
Numero componente immagine: 3 (Cr)
ID tabella Huffman per coefficienti DC: 1
[_1] ID tabella Huffman per coefficienti AC: 1

Questi componenti si alternano ciclicamente.

Qui è dove finisce la parte di intestazione, da qui alla fine (marcatore) dei dati codificati.


0

Trovare il coefficiente DC.
1. Lettura di una sequenza di bit (se incontriamo 2 byte, allora questo non è un marker, ma solo un byte)... Dopo ogni bit ci spostiamo lungo l'albero di Huffman (con il corrispondente identificatore) lungo i rami 0 o 1, a seconda del bit letto. Ci fermiamo se siamo nel nodo finale.
10 1011101110011101100001111100100

2. Prendiamo il valore del nodo. Se è 0, il coefficiente è 0, lo scriviamo nella tabella e procediamo alla lettura di altri coefficienti. Nel nostro caso - 02. Questo valore è la lunghezza del coefficiente in bit. Cioè, leggiamo i prossimi 2 bit, questo sarà il coefficiente.
10 10 11101110011101100001111100100

3. Se la prima cifra del valore in binario è 1, la lasciamo così com'è: DC_coef = value. Altrimenti, trasformiamo: DC_coef = valore-2 lunghezza del valore +1. Scriviamo il coefficiente nella tabella all'inizio dello zigzag - l'angolo in alto a sinistra.

Trovare i coefficienti AC.
1. Simile al punto 1, trovare il coefficiente DC. Continuiamo a leggere la sequenza:
10 10 1110 1110011101100001111100100

2. Prendiamo il valore del nodo. Se è uguale a 0, significa che i valori rimanenti della matrice devono essere riempiti con zeri. Quindi viene codificata la matrice successiva. I primi che hanno letto fino a questo punto e me ne hanno scritto in una personale, riceveranno un vantaggio in karma. Nel nostro caso, il valore del nodo è 0x31.
Primo nibble: 0x3 - questo è il numero di zeri che dobbiamo aggiungere alla matrice. Questi sono 3 coefficienti zero.
Secondo nibble: 0x1 - lunghezza del coefficiente in bit. Leggiamo il bit successivo.
10 10 1110 1 110011101100001111100100

3. Simile al punto 3 della ricerca del coefficiente DC.

Come hai già capito, devi leggere i coefficienti AC fino a quando non troviamo un valore di codice zero o fino a quando la matrice non è piena.
Nel nostro caso otteniamo:
10 10 1110 1 1100 11 101 10 0 0 0 1 11110 0 100
e la matrice:





Hai notato che i valori sono riempiti nello stesso ordine a zigzag?
La ragione per usare questo ordine è semplice: più grandi sono i valori di v e u, meno significativo è il coefficiente S vu nella trasformata discreta del coseno. Pertanto, ad alti rapporti di compressione, i coefficienti insignificanti vengono azzerati, riducendo così la dimensione del file.

[-4 1 1 1 0 0 0 0] [ 5 -1 1 0 0 0 0 0]
[ 0 0 1 0 0 0 0 0] [-1 -2 -1 0 0 0 0 0]
[ 0 -1 0 0 0 0 0 0] [ 0 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-1 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

[-4 2 2 1 0 0 0 0]
[-1 0 -1 0 0 0 0 0]
[-1 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Oh, ho dimenticato di dire che i coefficienti DC codificati non sono i coefficienti DC stessi, ma le loro differenze tra i coefficienti della tabella precedente (lo stesso canale)! È necessario correggere le matrici:
DC per il 2°: 2 + (-4) = -2
CD per il 3°: -2 + 5 = 3
CD per il 4°: 3 + (-4) = -1

[-2 1 1 1 0 0 0 0] [ 3 -1 1 0 0 0 0 0] [-1 2 2 1 0 0 0 0]
………

Ora è l'ordine. Questa regola dura fino alla fine del file.

... e per matrice per Cb e Cr:

[-1 0 0 0 0 0 0 0]
[ 1 1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Poiché qui c'è solo una matrice, i coefficienti DC possono essere lasciati soli.

Calcoli

Quantizzazione

Ricordi che la matrice passa attraverso la fase di quantizzazione? Gli elementi della matrice devono essere moltiplicati termine per termine con gli elementi della matrice di quantizzazione. Resta da scegliere quello di cui hai bisogno. Per prima cosa, abbiamo scansionato il primo componente, il suo componente immagine = 1. Il componente immagine con questo identificatore usa la matrice di quantizzazione 0 (abbiamo il primo dei due). Quindi dopo aver moltiplicato:


[ 0 120 280 0 0 0 0 0]
[ 0 -130 -160 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Allo stesso modo, otteniamo altre 3 matrici del canale Y ...

[-320 110 100 160 0 0 0 0] [ 480 -110 100 0 0 0 0 0]
[ 0 0 140 0 0 0 0 0] [-120 -240 -140 0 0 0 0 0]
[ 0 -130 0 0 0 0 0 0] [ 0 -130 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-140 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

[-160 220 200 160 0 0 0 0]
[-120 0 -140 0 0 0 0 0]
[-140 -130 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

... e per matrice per Cb e Cr.

[-170 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 180 210 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

Trasformata coseno discreta inversa

La formula non dovrebbe essere difficile *. S vu è la nostra matrice di coefficienti risultante. u è una colonna, v è una riga. s yx - valori di canale diretti.

* In generale, questo non è del tutto vero. Quando sono stato in grado di decodificare e visualizzare l'immagine 16x16 sullo schermo, ho scattato un'immagine 600x600 (a proposito, era la copertina dell'album preferito di Mind.In.A.Box, Lost Alone). Non ha funzionato subito: sono emersi vari bug. Presto ho potuto ammirare l'immagine correttamente caricata. Solo la velocità di download era molto sconvolgente. Ricordo ancora che ci vollero 7 secondi. Ma questo non è sorprendente, se usi sconsideratamente la formula sopra, quindi per calcolare un canale di un pixel, dovrai trovare 128 coseni, 768 moltiplicazioni e alcune aggiunte lì. Pensaci: quasi mille difficili operazioni su un solo canale di un pixel! Fortunatamente, c'è spazio per l'ottimizzazione (dopo molti esperimenti, ho ridotto il tempo di caricamento al limite di una precisione del timer di 15 ms, e successivamente ho cambiato l'immagine in una fotografia 25 volte più grande. Forse scriverò di questo in un articolo separato articolo).

Scriverò il risultato del calcolo solo della prima matrice del canale Y (i valori sono arrotondati):


[ 87 72 50 36 37 55 79 95]
[-10 5 31 56 71 73 68 62]
[-87 -50 6 56 79 72 48 29]

E i restanti 2:
Cb Cr
[ 60 52 38 20 0 -18 -32 -40] [ 19 27 41 60 80 99 113 120]
[ 48 41 29 13 -3 -19 -31 -37] [ 0 6 18 34 51 66 78 85]
[ 25 20 12 2 -9 -19 -27 -32] [-27 -22 -14 -4 7 17 25 30]
[ -4 -6 -9 -13 -17 -20 -23 -25] [-43 -41 -38 -34 -30 -27 -24 -22]
[ -37 -35 -33 -29 -25 -21 -18 -17] [-35 -36 -39 -43 -47 -51 -53 -55]
[ -67 -63 -55 -44 -33 -22 -14 -10] [ -5 -9 -17 -28 -39 -50 -58 -62]
[ -90 -84 -71 -56 -39 -23 -11 -4] [ 32 26 14 -1 -18 -34 -46 -53]
[-102 -95 -81 -62 -42 -23 -9 -1] [ 58 50 36 18 -2 -20 -34 -42]

  1. Oh, andiamo a mangiare!
  2. Sì, non entro affatto, di cosa si tratta.
  3. Una volta ricevuti i valori del colore YCbCr, resta da convertire in RGB, in questo modo: YCbCrToRGB (Y ij, Cb ij, Cr ij), Y ij, Cb ij, Cr ij - le nostre matrici risultanti.
  4. 4 matrici Y, e una ciascuna Cb e Cr, poiché abbiamo assottigliato i canali e 4 pixel di Y corrispondono a una Cb e Cr. Pertanto, calcola in questo modo: YCbCrToRGB (Y ij, Cb, Cr)
Se hai scelto 1 e 4, sono felice per te. O hai capito bene, o presto ti godrai il tuo pasto.

Da YCbCr a RGB

R = Y + 1,402 * Cr
G = Y - 0,34414 * Cb - 0,71414 * Cr
B = Y + 1,772 * Cb
Non dimenticare di aggiungere 128. Se i valori sono al di fuori dell'intervallo, assegnare i valori limite. La formula è semplice, ma consuma anche una frazione del tempo della CPU.

Ecco le tabelle risultanti per i canali R, G, B per il quadrato 8x8 in alto a sinistra del nostro esempio:
255 248 194 148 169 215 255 255
255 238 172 115 130 178 255 255
255 208 127 59 64 112 208 255
255 223 143 74 77 120 211 255
237 192 133 83 85 118 184 222
177 161 146 132 145 162 201 217
56 73 101 126 144 147 147 141
0 17 76 126 153 146 127 108

231 185 117 72 67 113 171 217
229 175 95 39 28 76 139 189
254 192 100 31 15 63 131 185
255 207 115 46 28 71 134 185
255 241 175 125 112 145 193 230
226 210 187 173 172 189 209 225
149 166 191 216 229 232 225 220
72 110 166 216 238 231 206 186

255 255 249 203 178 224 255 255
255 255 226 170 140 187 224 255
255 255 192 123 91 138 184 238
255 255 208 139 103 146 188 239
255 255 202 152 128 161 194 232
255 244 215 200 188 205 210 227
108 125 148 172 182 184 172 167
31 69 122 172 191 183 153 134

Fine

In generale, non sono uno specialista di JPEG, quindi difficilmente riesco a rispondere a tutte le domande. È solo che quando stavo scrivendo il mio decoder, ho avuto spesso a che fare con vari problemi incomprensibili... E quando l'immagine è stata visualizzata in modo errato, non sapevo dove ho commesso un errore. Forse ha interpretato male i bit, o forse ha abusato del DCT. Mi sono perso un esempio passo passo, quindi spero che questo articolo possa essere d'aiuto durante la scrittura di un decoder. Penso che copra la descrizione del metodo di base, ma ancora non puoi farlo. Ecco alcuni link che mi hanno aiutato:

È facile calcolare che un'immagine a colori non compressa di 2000 * 1000 pixel avrà una dimensione di circa 6 megabyte. Se parliamo di immagini ottenute da fotocamere professionali o scanner ad alta risoluzione, le loro dimensioni possono essere anche maggiori. Nonostante la rapida crescita della capacità di archiviazione, vari algoritmi di compressione delle immagini sono ancora molto rilevanti.
Tutti gli algoritmi esistenti possono essere suddivisi in due grandi classi:

  • Algoritmi di compressione senza perdite;
  • Algoritmi di compressione con perdita.
Quando parliamo di compressione senza perdita di dati, intendiamo che esiste un algoritmo che è l'opposto dell'algoritmo di compressione, che consente di ripristinare con precisione l'immagine originale. Non esiste un algoritmo inverso per gli algoritmi di compressione con perdita. Esiste un algoritmo che ripristina un'immagine che non corrisponde necessariamente esattamente a quella originale. Gli algoritmi di compressione e recupero sono selezionati per ottenere un elevato rapporto di compressione mantenendo la qualità visiva dell'immagine.

Algoritmi di compressione senza perdite

Algoritmo RLE
Tutti gli algoritmi della serie RLE si basano su un'idea molto semplice: i gruppi ripetuti di elementi vengono sostituiti da una coppia (numero di ripetizioni, elemento ripetuto). Consideriamo questo algoritmo usando una sequenza di bit come esempio. In questa sequenza si alterneranno gruppi di zero e uno. Inoltre, i gruppi avranno spesso più di un elemento. Quindi la sequenza 11111 000000 11111111 00 corrisponderà alla seguente serie di numeri 5 6 8 2. Questi numeri indicano il numero di ripetizioni (il conteggio inizia da uno), ma anche questi numeri devono essere codificati. Supponiamo che il numero di ripetizioni sia compreso tra 0 e 7 (cioè 3 bit sono sufficienti per codificare il numero di ripetizioni). Quindi la sequenza di cui sopra è codificata dalla seguente sequenza di numeri 5 6 7 0 1 2. È facile calcolare che sono necessari 21 bit per codificare la sequenza originale e nella forma compressa con RLE questa sequenza richiede 18 bit.
Sebbene questo algoritmo sia molto semplice, la sua efficacia è relativamente bassa. Inoltre, in alcuni casi, l'uso di questo algoritmo porta non ad una diminuzione, ma ad un aumento della lunghezza della sequenza. Ad esempio, si consideri la seguente sequenza 111 0000 11111111 00. La sequenza RL corrispondente ha questo aspetto: 3 4 7 0 1 2. La lunghezza della sequenza originale è di 17 bit, la lunghezza della sequenza compressa è di 18 bit.
Questo algoritmo è più efficace per le immagini in bianco e nero. Viene spesso utilizzato anche come uno degli stadi intermedi di compressione di algoritmi più complessi.

Algoritmi del dizionario

L'idea alla base degli algoritmi del dizionario è che le stringhe di elementi nella sequenza originale sono codificate. In questa codifica viene utilizzato un dizionario speciale, ottenuto dalla sequenza originale.
Esiste un'intera famiglia di algoritmi di vocabolario, ma esamineremo l'algoritmo LZW più comune, che prende il nome dai suoi sviluppatori Lepel, Ziv e Welch.
Il dizionario in questo algoritmo è una tabella che viene riempita con stringhe di codifica durante l'esecuzione dell'algoritmo. Durante la decodifica del codice compresso, il dizionario viene ripristinato automaticamente, quindi non è necessario trasferire il dizionario insieme al codice compresso.
Il dizionario è inizializzato con tutte le stringhe singleton, ad es. le prime righe del dizionario rappresentano l'alfabeto in cui stiamo codificando. La compressione cerca la catena più lunga già scritta nel dizionario. Ogni volta che si incontra una stringa che non è stata ancora scritta nel dizionario, viene aggiunta lì e viene emesso un codice compresso corrispondente alla stringa già scritta nel dizionario. In teoria, non vengono imposte restrizioni alla dimensione del dizionario, ma in pratica ha senso limitare questa dimensione, poiché nel tempo iniziano a verificarsi catene che non si trovano più nel testo. Inoltre, quando la dimensione della tabella viene raddoppiata, dobbiamo allocare un bit in più per memorizzare i codici compressi. Per evitare tali situazioni, viene introdotto un codice speciale che simboleggia l'inizializzazione della tabella da parte di tutte le stringhe singleton.
Consideriamo un esempio di compressione da parte dell'algoritmo. Stringeremo la corda del cuculo, il cuculo, il cuculo ha comprato il cappuccio. Supponiamo che il dizionario contenga 32 posizioni, il che significa che ciascuno dei suoi codici occuperà 5 bit. Inizialmente, il dizionario è compilato come segue:

Questa tabella è, sia dalla parte di chi comprime le informazioni, sia dalla parte di chi disimballa. Ora esamineremo il processo di compressione.

La tabella mostra il processo di compilazione del dizionario. È facile calcolare che il codice compresso risultante richiede 105 bit e il testo originale (assumendo che si spendano 4 bit per codificare un carattere) richiede 116 bit.
In effetti, il processo di decodifica si riduce alla decifratura diretta dei codici, mentre è importante che la tabella venga inizializzata allo stesso modo della codifica. Ora diamo un'occhiata all'algoritmo di decodifica.


Possiamo definire completamente la stringa aggiunta al dizionario al passaggio i-esimo solo a i + 1. Ovviamente la i-esima riga deve terminare con il primo carattere i + 1 della riga. Quella. abbiamo appena capito come ripristinare un dizionario. Di un certo interesse è la situazione in cui viene codificata una sequenza della forma cScSc, dove c è un carattere e S è una stringa e la parola cS è già nel dizionario. A prima vista può sembrare che il decoder non sia in grado di risolvere questa situazione, ma in realtà tutte le linee di questo tipo devono terminare sempre con lo stesso carattere con cui iniziano.

Algoritmi di codifica entropia
Gli algoritmi di questa serie assegnano il codice compresso più breve agli elementi di sequenza più frequenti. Quelli. sequenze della stessa lunghezza sono codificate con codici compressi di lunghezze diverse. Inoltre, più spesso si verifica la sequenza, più breve è il codice compresso corrispondente.
Algoritmo di Huffman
L'algoritmo di Huffman ti consente di creare codici di prefisso. Puoi pensare ai codici di prefisso come percorsi su un albero binario: il passaggio da un nodo al suo figlio sinistro corrisponde a 0 nel codice, e al suo figlio destro - 1. Se contrassegniamo le foglie dell'albero con caratteri codificati, ottenere una rappresentazione ad albero binario del codice del prefisso.
Descriviamo un algoritmo per costruire un albero di Huffman e ottenere codici di Huffman.
  1. I caratteri nell'alfabeto di input formano un elenco di nodi liberi. Ogni foglio ha un peso pari alla frequenza di occorrenza del simbolo
  2. Vengono selezionati due nodi liberi dell'albero con i pesi minori
  3. Il loro genitore viene creato con un peso pari al loro peso totale
  4. Il genitore viene aggiunto all'elenco dei nodi liberi e i suoi due figli vengono rimossi da questo elenco
  5. Ad un arco che esce dal genitore viene assegnato il bit 1, l'altro - bit 0
  6. I passaggi a partire dal secondo vengono ripetuti fino a quando nella lista libera rimane un solo nodo libero. Sarà considerato la radice dell'albero.
Usando questo algoritmo, possiamo ottenere i codici di Huffman per un dato alfabeto, tenendo conto della frequenza di occorrenza dei caratteri.
Codifica aritmetica
Gli algoritmi di codifica aritmetica codificano stringhe di elementi in frazioni. Ciò tiene conto della distribuzione di frequenza degli elementi. Al momento, gli algoritmi di codifica aritmetica sono protetti da brevetti, quindi considereremo solo l'idea di base.
Lascia che il nostro alfabeto sia composto da N simboli a1,..., aN, e le frequenze della loro occorrenza siano p1,..., pN, rispettivamente. Dividiamo il semiintervallo)

Principali articoli correlati