Se un'immagine viene ruotata senza perdita di dati, perché cambia la dimensione del file?


37

Stavo cercando metodi di rotazione delle immagini senza perdita e mi sono imbattuto in questa domanda che la spiega piuttosto bene:

Le rotazioni di "Windows Photo Viewer" sono senza perdita?

Quindi ho creato un JPEG 256 × 256 con pixel casuali (filtro cloud Photoshop) e poi l'ho ruotato usando il Visualizzatore immagini di Windows. Dopo la rotazione, la dimensione del file è effettivamente aumentata, ma solo alla prima rotazione. Ogni successiva rotazione successiva, la dimensione del file è rimasta statica. So che sta ruotando senza perdita perché l'ho ruotato più volte senza alcuna perdita di qualità evidente mentre un'immagine 257 × 257 ruotata 20 volte è diventata molto perdita.


8
Di quanto è aumentata la dimensione del file nei test?
James Snell,

3
@JamesSnell Sapevo che avrei dovuto includerlo. Quello che ho appena fatto usando il filtro clounds di differenza di GIMP era originariamente di 14.583 byte, ma è cambiato in 23.638 byte dopo il roation. Questa è una differenza di oltre 9000 byte che sembra un sacco di dati aggiuntivi se stiamo parlando solo dei metadati.
oscilatingcretin

4
Sembra molti metadati aggiuntivi. Non sarei troppo veloce per assumere tutti quei dati aggiuntivi come metadati. Mi sembra che la differenza di dimensioni dovuta ai metadati dovrebbe essere quasi una costante (entro pochi byte per tenere conto della rappresentazione di stringhe di alcuni numeri).
Scott

4
Quando si forniscono informazioni aggiuntive che sono pertinenti alla domanda, si prega di modificare la domanda anziché nei commenti. I commenti sono effimeri e possono essere ripuliti di volta in volta.
Scott

2
Il caricamento della versione originale dell'immagine di prova sarebbe utile.
CodesInChaos

Risposte:


36

Ciò è probabilmente causato dalla codifica entropica , che è lo stadio finale senza perdita di compressione JPEG, dopo che i dati dell'immagine sono stati quantizzati per ridurne le dimensioni.

Quando un'immagine JPEG viene ruotata senza perdita, questo ultimo strato di codifica senza perdita deve essere annullato, i coefficienti DCT non compressi vengono mescolati e quindi i coefficienti mescolati devono essere nuovamente codificati entropia. Poiché l'efficienza del livello di codifica entropia dipende dall'ordine dei coefficienti DCT all'interno di ciascun blocco, la rotazione dell'immagine cambierà, non dovrebbe sorprendere che il file di immagine ruotato possa essere più piccolo o più piccolo di qualche percentuale rispetto all'originale.

Esistono anche diversi modi in cui è possibile eseguire la fase di codifica dell'entropia, quindi è del tutto possibile che la dimensione del file della stessa identica immagine JPEG possa variare a seconda del software che esegue la codifica. Alcune delle potenziali differenze tra gli encoder includono:

  • scelta della codifica aritmetica (rara ma potenzialmente più efficiente, utilizzata per essere brevettata) rispetto alla codifica Huffman (più semplice, standard);
  • scelta del sequenziale (ogni blocco di 8x8 pixel è codificato uno alla volta) rispetto al progressivo (i componenti a bassa frequenza di tutti i blocchi sono codificati prima dei componenti a frequenza più alta, di solito leggermente più compatti);
  • scelta di utilizzare le tabelle dei simboli Huffman standard (più veloce, più semplice, può essere più efficiente per immagini molto piccole) rispetto alle tabelle personalizzate ottimizzate per ogni immagine (di solito più efficienti per immagini di grandi dimensioni, più lente e più complesse da codificare);
  • se si utilizzano tabelle Huffman personalizzate, codificatori diversi potrebbero potenzialmente generare tabelle diverse per gli stessi dati immagine;
  • vari dettagli di basso livello del processo di codifica stesso, come se e quando includere i marker di riavvio nel flusso di dati, possono anche variare tra i codificatori.

Inoltre, i "file JPEG" con cui normalmente lavorano le persone contengono in realtà dati di immagine compressi in JPEG avvolti in un contenitore JFIF o Exif , che combina i dati di immagine con uno o più blocchi di metadati e introduce una propria serie di complicazioni. Anche se il software che ruota l'immagine in realtà non apporta modifiche sostanziali ai metadati JFIF / Exif, semplicemente riorganizzare i dati potrebbe potenzialmente influire sulla dimensione del file di alcuni byte.

In particolare, i metadati JFIF / Exif possono contenere una o più miniature dell'immagine a dimensione intera e il software che ruota le immagini dovrebbe davvero rigenerare (o anche ruotare senza perdita di dati!) Le miniature in modo che corrispondano al nuovo orientamento del pieno- immagine di dimensioni. Questo da solo potrebbe facilmente spiegare la differenza di dimensione osservata.


4
Per una differenza di 9 KB (60%), la mia ipotesi sarebbe di miniature.
BlueRaja - Danny Pflughoeft

JPEG potrebbe essere troppo semplice perché valga la pena farlo con gli encoder, ma gli encoder video come x264 possono effettivamente considerare la capacità del codificatore di ingresso di codificare ciò che stanno per produrre successivamente, quando prendono decisioni di compromesso tra velocità e distorsione. (vale a dire decidere quanti bit potrebbe costare ciascuna alternativa e valutarlo rispetto all'errore con perdita). Questo si chiama quantizzazione a traliccio. Vedi Note sull'implementazione della quantizzazione a traliccio in H.264 dell'autore di x264 (Loren Merritt); inizia con una spiegazione piuttosto semplice dello scopo.
Peter Cordes,

Comunque, il codificatore JPEG potrebbe aver scelto i coefficienti DCT in modo tale da comprimersi bene con il codificatore di entropia, quindi anche un compressore ottimale non potrebbe rendere una versione ruotata così piccola. (Perché metterli in un ordine diverso probabilmente li farebbe comprimere meno bene.) Questo sarebbe quasi certamente un piccolo effetto per JPEG, poiché ogni blocco 8x8 è codificato separatamente (ripristinando lo stato del codificatore di entropia, AFAIK). (I fotogrammi I in h.264 usano la predizione intra, predicendo da altri blocchi nello stesso fotogramma, rendendoli più piccoli di un JPEG con la stessa qualità visiva.)
Peter Cordes

24

Sono andato avanti e ho ripetuto l'esperimento per vedere se potevo capire cosa stava succedendo.

Procedura

Ho generato un'immagine RGB casuale da 256 per 256 pixel utilizzando il filtro "Rumore solido" in GIMP (Filtri> Rendering> Nuvole> Rumore solido ...) utilizzando le impostazioni predefinite (mostrate di seguito):

inserisci qui la descrizione dell'immagine

E il risultato:

inserisci qui la descrizione dell'immagine

Quindi ho salvato l'immagine come JPEG usando le impostazioni predefinite:

inserisci qui la descrizione dell'immagine

Quindi ho trasferito l'immagine su Windows e ho aperto l'immagine con Windows Photo Viewer facendo clic con il tasto destro sull'immagine in Esplora file e scegliendo Anteprima dal menu. Quindi ho ruotato l'immagine usando i pulsanti in basso e ho salvato l'immagine passando all'immagine successiva usando i tasti freccia.

Per ciascuno dei test seguenti ho iniziato con una copia dell'immagine originale e ruotato (facendo clic sul pulsante di rotazione) il numero corrispondente di volte prima di salvare. Ecco le dimensioni corrispondenti ( ls -l -r):

                    size in bytes    last-modified date 
                          VVVVV        VVVVV
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:24 original.jpg
-rwxrwx--- 1 root vboxsf  23645 Nov  8 11:30 cw.jpg
-rwxrwx--- 1 root vboxsf  23636 Nov  8 11:30 cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:30 cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:27 cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:31 cw-cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:29 ccw.jpg
-rwxrwx--- 1 root vboxsf  23636 Nov  8 11:29 ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf  23645 Nov  8 11:29 ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:27 ccw-ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:30 ccw-ccw-ccw-ccw-ccw.jpg

Osservazioni immediate

  • Windows Photo Viewer (WPV) aumenta notevolmente le dimensioni; la quantità di aumento è di circa quattro volte in questo test!
  • Tutte le nuove immagini aumentano circa della stessa dimensione, ma non sono identiche.
  • Il WPV non ricodifica né salva nuovamente l'immagine quando viene ruotata di un multiplo di 360 gradi. (Il timestamp, 11:27, è quando i file sono stati copiati per la prima volta.)

L'utilizzo cmp -lsu file che dovrebbero avere un contenuto identico ci consente di vedere dove differiscono i file.

robert@unity ../jpeg-rotate-test % cmp -l cw.jpg ccw-ccw-ccw.jpg
 2223  63  62
 2224  60  71
 2226  60  64
 2227  60  66
robert@unity ../jpeg-rotate-test % cmp -l cw-cw.jpg ccw-ccw.jpg
 2223  63  62
 2224  60  71
 2226  60  64
 2227  62  64
robert@unity ..jpeg-rotate-test % cmp -l ccw.jpg cw-cw-cw.jpg
 2223  62  63
 2224  71  60
 2226  64  60
 2227  61  64
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg cw-cw-cw-cw-cw.jpg
 2221  60  61
 2223  63  61
 2224  60  66
 2226  60  61
 2227  60  61
robert@unity ../jpeg-rotate-test % cmp -l ccw.jpg ccw-ccw-ccw-ccw-ccw.jpg
 2223  62  63
 2224  71  60
 2226  64  65
 2227  61  64

Questi file differiscono in soli quattro byte (in realtà in un timestamp), il che significa che WPV fa sempre la stessa cosa; ora dobbiamo solo capire di cosa si tratta.

Osservazioni dettagliate

Per questo ho usato JPEGsnoop per vedere cosa fosse esattamente nelle immagini.

Dal momento che le uscite sono piuttosto lunghe, le ho collegate come sostanza . Ecco un riepilogo delle differenze:

  • GIMP utilizza solo un segmento APP0(JFIF) e COM(commento) per i metadati. WPV lascia il APP0segmento intatto, ma stranamente aggiunge un byte nullo al commento (in modo che sia nullo).

  • WPV aggiunge due APP1segmenti, che sono metadati Exif e XMP. Questi segmenti sono rispettivamente 4286 e 12726 byte. Insieme rappresentano quasi l'intero aumento della dimensione dei file.

  • GIMP produce un JPEG progressivo, mentre WPV produce un JPEG di base (non progressivo). Per questo motivo l'immagine di GIMP ha più segmenti di scansione, mentre l'immagine WPV ne ha solo uno. Nella mia esperienza, l'immagine progressiva a volte è leggermente più piccola.

  • GIMP ha usato il sottocampionamento cromatico 1 × 1, mentre WPV ha usato il sottocampionamento 2 × 2. Questo mi porta a credere che WPV non stia usando una rotazione "vera" senza perdita, a meno che non sia in qualche modo in grado di rilevare questa immagine in bianco e nero.

Per risolvere questi problemi, ho eseguito un secondo test.

Procedura

Ho seguito passaggi simili al primo test. Ho creato un'immagine RGB 256 × 256 casuale usando il filtro Rumore RGB (Filtri> Naso> Naso RGB ...) con le seguenti impostazioni:

inserisci qui la descrizione dell'immagine

Ecco il risultato:

inserisci qui la descrizione dell'immagine

Ho esportato il file come JPEG utilizzando le seguenti impostazioni:

inserisci qui la descrizione dell'immagine

Progressivo è stato disattivato, ma il sottocampionamento è ancora impostato su 4: 4: 4 (che è un altro nome per il sottocampionamento 1 × 1). La qualità è aumentata a 98.

Ho copiato l'immagine e ruotato la copia in senso orario; quindi copiato la versione ruotata e ruotata quella copia in senso antiorario, in modo da poter confrontare direttamente la qualità tra l'originale e la copia elaborata da WPV.

risultati

-rwxrwx--- 1 root vboxsf 159774 Nov  8 16:21 original-random.jpg
-rwxrwx--- 1 root vboxsf 222404 Nov  8 16:24 cw-random.jpg
-rwxrwx--- 1 root vboxsf 222467 Nov  8 16:24 cw-ccw-random.jpg

Sebbene l'aumento questa volta sia minore in termini relativi (circa il 40%), l'aumento assoluto è ancora maggiore: circa 62 kB. Ciò suggerisce che WMV sta utilizzando una codifica meno efficiente.

Userò ImageMagick per confrontare le due immagini:

robert@unity ../jpeg-rotate-test % compare -verbose -metric AE original-random.jpg cw-ccw-random.jpg null:
original-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 160KB 0.000u 0:00.009
cw-ccw-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 222KB 0.010u 0:00.010
Image: original-random.jpg
  Channel distortion: AE
    red: 0
    green: 0
    blue: 0
    all: 0
original-random.jpg=> JPEG 256x256 256x256+0+0 8-bit sRGB 0.050u 0:00.020

Vi sono zero pixel diversi tra la copia originale e quella ruotata. Quindi, anche se WPV non utilizza una rotazione senza perdita "vera", sta facendo un lavoro abbastanza buono. Sospetto di sapere cosa stia succedendo e per spiegare mi sposterò un po 'nella matematica dietro la compressione JPEG.

L'algoritmo di compressione JPEG suddivide un'immagine in blocchi di 8 × 8 pixel. Ciascuno di questi blocchi viene quindi sottoposto a una trasformazione discreta del coseno (DCT) . I coefficienti DCT risultanti descrivono il blocco come una somma di onde a frequenza diversa. L'algoritmo quindi "getta via" alcune informazioni nelle onde ad alta frequenza che corrispondono al rumore e ai dettagli molto piccoli. Il processo di decodifica inverte il DCT, sommando le onde memorizzate per ripristinare il blocco.

È possibile ruotare le "onde" DCT senza effettivamente annullare e ripetere la trasformazione (in pratica si trasformano tutte le onde orizzontali in onde verticali e viceversa). Ciò che penso accada in WPV è che l'immagine viene effettivamente decodificata, ruotata e quindi ricodificata. Durante il processo di ricodifica, poiché la dimensione della nostra immagine è un multiplo di 8 in entrambe le dimensioni, ciascuno dei nuovi blocchi corrisponde a uno dei blocchi originali. È importante sottolineare che, poiché ogni blocco non ha componenti ad alta frequenza, l'algoritmo non elimina alcuna informazione e trova esattamente i componenti DCT giusti che avrebbe una rotazione "vera" senza perdita.

Infine, esaminerò di nuovo i componenti dei file JPEG. I risultati vengono nuovamente collegati come sintesi . Confrontando i due:

  • L'immagine WPV contiene 4286 + 2 byte extra di metadati Exif, 1 byte extra nel commento e 12.726 + 2 byte di metadati XMP. Questo è un totale di 17.017 byte di metadati aggiuntivi. A cosa servono tutti quei dati? Ho scrutato il file con il mio fidato editor esadecimale e una copia degli standard pertinenti:

    • I metadati Exif sono strutturati come un'immagine TIFF, che contiene una serie di tag (c'è molta più complessità, ma la salterò sopra). La maggior parte dei byte nel segmento Exif sono contenuti in due tag identici con numero di tag EA1C(59.932 decimale). Quel numero di tag non è documentato da nessuna parte che ho potuto trovare. Entrambi i tag contengono 2060 byte di tipo "non definito", che sono tutti byte null tranne i primi sei ( 1C EA 00 00 00 08). Non ho idea di cosa siano questi tag, perché ce ne siano due e perché debbano essere di 2 kB ciascuno.

    • I metadati XMP sono in realtà un intero documento XML incorporato con spazio dei nomi e UUID lunghi, che contiene solo la stringa della versione WPV (che era già nei metadati Exif). Tuttavia, ciò rappresenta solo circa 400 byte. Il resto del segmento è 122 ripetizioni di 100 spazi seguiti da una nuova riga . Sono oltre 12.000 byte di spazio totalmente sprecato.

  • Come il test precedente, sia GIMP che WPV utilizzano le stesse tabelle di quantizzazione DCT. Ciò significa che dovrebbero calcolare esattamente gli stessi coefficienti DCT, motivo per cui le immagini sono esattamente le stesse. Non sono sicuro se WPV stia utilizzando le stesse tabelle di quantizzazione o se copi le tabelle dall'input.

  • A differenza del test precedente, questa volta WPV utilizza il sottocampionamento 1 × 1, quindi potrebbe effettivamente rilevare che si tratta di un'immagine a colori (o almeno che sono necessari campioni più alti per ricodificare senza perdita di immagine).

  • GIMP e WPV utilizzano diverse tabelle Huffman (parte della fase di codifica dell'entropia). Le tabelle per WPV sono più grandi di un totale di 279 byte e in un caso contengono 7 volte più codici.

    Osservando le statistiche di JPEGsnoop, possiamo vedere che alcuni di questi codici sono usati raramente. Ad esempio, nella ID: 1, Class: ACtabella, dei 119 codici a 16 bit definiti, solo 23 sono effettivamente utilizzati. Nel complesso, il segmento di scansione effettivo è maggiore del 28,5% nella versione WPV.

Sommario

  • Il WPV potrebbe non fare rotazioni "vere" senza perdita, ma le rotazioni sembrano essere praticamente senza perdita.

  • Le dimensioni extra sono in parte dovute a una quantità fissa di metadati aggiunti e in parte a una codifica entropica meno efficiente.

Informazioni sulla versione:

  • OS (Linux) ( uname -a):

    Linux unity 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux
    
  • Sistema operativo (Windows):

    inserisci qui la descrizione dell'immagine

  • GIMP (Linux): 2.8.14 (dal pacchetto gimp, versione 2.8.14-1+deb8u1)

    inserisci qui la descrizione dell'immagine

  • Window Photo Viewer (secondo i metadati delle immagini):

    Microsoft Windows Photo Viewer 10.0.10586.0
    

20

EDIT : Questa risposta è stata pubblicata prima che sapessi che le dimensioni dei file erano aumentate di circa 9 KiB (9055 byte per l'immagine 256 × 256, 9612 KiB per l'immagine 512 × 512).

Con ogni probabilità, quando hai ruotato l'immagine per la prima volta, Windows Picture Viewer ha eseguito una (o entrambe) le seguenti operazioni:

  1. Aggiunto un tag EXIF ​​che non era nell'immagine JPEG originale (forse il tag di orientamento);
  2. Informazioni modificate / aggiunte a un tag già esistente (forse tag Software di elaborazione o Software immagine).

Ciò ha aumentato le dimensioni del file a causa del tag EXIF ​​aggiuntivo (e / o dei dati aggiuntivi ai tag esistenti).

Le rotazioni successive non hanno aumentato le dimensioni del file perché tutti i tag e / o i dati dei tag che WPV avrebbe aggiunto / modificato erano già presenti. È cambiato solo il valore del tag di orientamento (e forse anche i valori dei tag di data / ora).


EDIT : è quasi certo che questa spiegazione non può rappresentare circa 9 KiB di dati aggiuntivi nel file. Inoltre, in assenza di altre ragioni per l'aumento delle dimensioni, questa spiegazione si aspetterebbe che l'aumento delle dimensioni sarebbe più o meno costante (modulo alcune differenze di lunghezza tra le rappresentazioni di stringhe di dati numerici, probabilmente alcuni byte). Ovviamente non è quello che sta succedendo qui, almeno non la spiegazione completa.


1
E un tag EXIF ​​occuperà 9kB? Bene, almeno questo è facile da testare: chiedi all'OP di eliminare EXIF ​​o altri tag dall'immagine ruotata e vedere come cambia la dimensione del file.
Carl Witthoft,

2
@CarlWitthoft il 9kB è una nuova informazione. Editing per menzionarlo.
Scott

3

Senza il reverse engineering del jpeg en / decoder è impossibile dirlo con certezza. Esistono in realtà numerosi standard jpeg e contrariamente alla credenza popolare, non tutti possono essere modificati senza ricodifica.

È possibile che il primo salvataggio sia una riscrittura con perdita nel suo sapore jpeg preferito e le successive rotazioni sono una semplice modifica dei metadati o un'operazione direttamente sulla tabella DCT (che è possibile per alcuni schemi di codifica).

L'aumento della dimensione dei file può anche includere alcuni metadati aggiuntivi, sebbene 9k sembri molto, è possibile. L'aumento può anche essere giustificato dall'aggiunta di una miniatura che potrebbe non essere stata presente nell'output di GIMP. Potremmo essere in grado di ottenere ulteriori informazioni direttamente dai file (prima di WPV e dopo).

In ogni caso, provare a lavorare senza problemi con jpeg è davvero una follia, in quanto è utile solo con determinate dimensioni di immagine, non tutti i decodificatori e gli encoder sono identici e richiede che quegli editor lavorino direttamente con il contenuto jpeg su cui non puoi fare affidamento il caso ... Solo perché lo fa ora non significa che continuerà a farlo in futuro.

La tua scommessa migliore è quella di lavorare con un formato senza perdita ed evitare del tutto il dolore.


2
Non sono affatto convinto che la rotazione dei dati jpeg dovrebbe causare in primo luogo una ricodifica.
Carl Witthoft,

Dipende se sei un programmatore o no ... Suppongo che non lo sia. Dovresti cercare specificamente quell'ottimizzazione per apportare quel minimo cambiamento altrimenti un'operazione di salvataggio partirà dalla bitmap non compressa.
James Snell,

3
Dalla domanda collegata, è chiaro che Windows Photo Viewer ruota JPEG senza perdita di dati.
vclaw

2
@James Non sono un programmatore di basso livello, anche se suono in TV :-). L'OP ha fornito un collegamento a una descrizione accurata di quando ci sarebbe la ricodifica e quando non lo sarebbe. Da quella discussione avevo dedotto che stava solo ruotando di $ \ frac {\ pi} {2} $. Concordo sul fatto che la rotazione angolare arbitraria causi la ricodifica, e in tal caso causerà la perdita di informazioni a meno che l'immagine X-by-Y non sia incorporata in una regione grande almeno quanto l'ipotenusa.
Carl Witthoft,

1
Siamo abbastanza sicuri di sapere che WPV sta ruotando in modo reversibile per immagini con dimensioni multiple di 8/16. Vedi il commento di @ Tristan alla risposta di Matt Grum alla domanda collegata nel PO. Tristan ha lavorato nel team WPV di Microsoft e sostanzialmente lo conferma.
Scott

1

La rotazione JPEG senza perdita di dati è possibile solo senza l'introduzione di artefatti al contorno se le dimensioni dell'immagine sono multiple della dimensione del blocco (in genere [/ sempre?] 8). Vedi la pagina man di jpegtran (scusate se non ho un buon link canonico per questo; sentitevi liberi di modificarlo se ne trovate uno) per i dettagli su ciò che è coinvolto:

La trasformazione di trasposizione non ha restrizioni per quanto riguarda le
dimensioni dell'immagine . Le altre trasformazioni funzionano in modo piuttosto strano se le dimensioni dell'immagine non sono un multiplo della dimensione iMCU (normalmente 8 o 16 pixel), poiché possono trasformare blocchi completi di dati del coefficiente DCT nel modo desiderato.

Il comportamento predefinito di jpegtran quando si trasforma un'immagine di dimensioni dispari
è progettato per preservare l'esatta reversibilità e
coerenza matematica dell'insieme di trasformazioni. Come detto, la trasposizione è in
grado di capovolgere l'intera area dell'immagine. Il mirroring orizzontale lascia intatta qualsiasi colonna iMCU parziale sul bordo destro, ma è in grado di capovolgere tutte le righe dell'immagine. Allo stesso modo, il mirroring verticale lascia intatta qualsiasi riga iMCU parziale sul bordo inferiore, ma è in grado di capovolgere tutte le colonne. Le altre trasformazioni possono essere costruite come sequenze di operazioni di trasposizione e inversione; per coerenza, le loro azioni sui pixel dei bordi sono definite come uguali al risultato finale della corrispondente sequenza di trasposizione e capovolgi.

Per un uso pratico, potresti preferire scartare tutti i
pixel dei bordi non trasformabili piuttosto che avere una striscia dall'aspetto strano lungo i
bordi destro e / o inferiore di un'immagine trasformata. Per fare ciò, aggiungi l'opzione -trim:

Sospetto che Windows Photo Viewer stia evitando questo problema eseguendo la decompressione e la ricompressione di altissima qualità per simulare comportamenti senza perdita quando le dimensioni dell'immagine non sono multipli di 8, piuttosto che eseguire effettivamente una rotazione senza perdita. Una buona utility farebbe solo veri e propri artefatti senza perdita di dati o eliminerebbe alcuni pixel, anziché rovinare la qualità dell'intera immagine (e aumentare le dimensioni del file).


1
irrilevante per un'immagine 256x256.
THS

Ho letto male e ho pensato che il problema fosse per la versione 257x257.
R ..

0

Non ho una risposta definitiva ma alcune possibili teorie sul perché ciò sia accaduto. Alcuni tipi di file funzionano in modo che due codici diversi per un'immagine di quel tipo di file non producano necessariamente immagini diverse. Ad esempio, il tipo di file PNG funziona in questo modo perché consente uno sfondo trasparente ma un'immagine con uno sfondo trasparente e uno uguale, tranne per il fatto che lo stesso sfondo bianco appare esattamente allo stesso modo. Si dice che un file di immagine sia compresso se occupa meno di 3 byte di memoria per pixel. Credo che, tranne quelli con uno sfondo trasparente, non ci siano due file PNG che generano la stessa identica immagine. Ogni volta che salvi un'immagine come PNG, la converte in un codice che genera l'immagine originale e ad eccezione di immagini molto insolite come una in cui ogni pixel è un colore casuale di tutti i 2 ^ 24 colori, il codice occuperà meno memoria di 3 byte per pixel, risparmiando così come si dice che PNG sia una compressione senza perdita. D'altra parte, per risparmiare memoria, solo alcune immagini possono essere generate dal codice di un file immagine JPEG. Probabilmente c'è più di un tipo di file JPEG e non so se qualcuno di loro abbia la proprietà che due diverse immagini di quel tipo di file possano generare esattamente la stessa immagine. Suppongo che un sacco di volte hai appena ruotato un'immagine, quindi l'hai salvata come JPEG e fornirai una spiegazione di ciò che è accaduto partendo dal presupposto che è quello che hai fatto che non so se sia vero. Una rotazione che hai fatto è senza perdita se c'è un modo per recuperare esattamente lo stesso codice di file immagine che avevi prima di ruotarlo e salvarlo. Potresti non avere ragione nel dire che hai davvero fatto una rotazione senza perdita. Se fosse davvero senza perdite,


-3

I motivi alla base di questo sono alcuni

il modo in cui le immagini vengono codificate e compresse cambierà la dimensione semplicemente a causa dell'algoritmo di compressione. puoi testarlo salvandolo come bitmap e ruotandolo. In quel formato o in qualsiasi formato non elaborato la dimensione dovrebbe rimanere la stessa. In caso contrario, il programma che salva l'immagine sta aggiungendo nuovi dati, possibilmente alcuni metadati o qualcosa del genere.

Ma perché stai ruotando un jpeg 20 volte?


2
Se leggi il link nella domanda originale, almeno per Windows Picture Viewer , se le dimensioni di un JPEG sono un multiplo di 8, le rotazioni di JPEG in WPV sono trasformazioni senza perdita. Un modo semplice per testare è quello di ruotare 4 volte (con lo stesso orientamento dell'originale) ed eseguire una semplice sottrazione dell'immagine pixel per pixel.
Scott

@scottbb Questo non è necessariamente solo un problema con il visualizzatore di immagini di Windows. Tutto ciò che ruota un formato con perdita deve ricalcolare la compressione. la rotazione di un'immagine in multipli di 8 significa che tutto si adatta a parole di 8 bit e potrebbe non essere compresso in modo da aggiungere artefatti. Questo si basa su come funziona l'algoritmo e viene implementato nel programma utilizzato.
Cc Dd,

-3

A causa di come funziona la compressione delle immagini . Qualsiasi formato come PNG o JPG in generale non conserva le dimensioni del file dopo la rotazione.

Per il compressore l'immagine ruotata è solo un'immagine diversa, a causa del modo in cui l'euristica della compressione funziona, non vi è alcuna garanzia che comprimerà un'immagine ruotata allo stesso modo .

Naturalmente se la compressione è senza perdita di dati, se si ruota l'immagine 4 volte la 4a volta l'immagine è di nuovo la stessa (ruotata fino a quando non viene inclinata come originale): in tal caso dovrebbe tornare di nuovo della stessa dimensione compressa, in caso contrario è perché uno dei seguenti motivi :

  • Aggiunti metadati : il programma ha aggiunto un po 'di testo per qualche motivo
  • Compressore modificato: il programma può scegliere di ri-salvare l'immagine come originale se non ci sono modifiche, ma se si applica qualsiasi modifica (anche 4 rotazioni di 90 gradi) può decidere di ricomprimere nuovamente l'immagine usando la propria compressore (il programma non sa più che è sempre la stessa immagine).
  • In generale lo stesso compressore (libPNG o libJPG) produce risultati molto diversi tra implementazioni diverse, versioni diverse della stessa libreria e con parametri di compressione diversi (anche il sistema operativo e il compilatore fanno la differenza qui a volte).

La compressione delle immagini funziona comprimendo le immagini in blocchi 4x4 o di altre dimensioni. In generale un compressore vede un'immagine ruotata come un'immagine diversa, tuttavia poiché un blocco di pixel compressi è solo una decomposizione lineare, se i blocchi sull'immagine sono uguali, è possibile solo trasporre / rispecchiare le matrici di decomposizione lineare mantenendo efficacemente lo stesso qualità:

Nota che questo deve essere implementato in base alla funzione e che spiega anche l'aumento iniziale di size => alla prima rotazione cerca solo di comprimere l'immagine in blocchi che sono ruotabili:

  • In caso contrario: la qualità dell'immagine peggiora
  • Se ha successo, aumenta le dimensioni solo una volta, quindi ogni rotazione mantiene la stessa qualità.

  • Tale operazione ha esito positivo solo se l'immagine è composta da blocchi uguali. (la dimensione dell'immagine è multipla della dimensione del pezzo).

Lo scottbb risponde male e puoi fare un semplice test:

  • Apri l'immagine originale: screenshot
  • Ruota l'immagine 4 volte con WPV: Screenshot
  • Confronta i 2 screenshot

Vedrai l'immagine cambiata (viene ricompressa alla prima rotazione). Tuttavia, tale modifica è limitata nel tempo, ora puoi ruotarla di nuovo senza perdita di qualità (se l'immagine ha una dimensione che è un multiplo di 8)

Per rispondere direttamente a OP:

So che sta ruotando senza perdita di dati

Non ruota senza perdita, perde qualità almeno una volta (alla prima rotazione: perché prima dovrebbe comprimerlo in un modo che può essere ruotato), quindi mantiene la sua qualità.


1
La domanda riguarda la rotazione senza perdita, quindi si evita la ricompressione.
Agent_L

5
OP non ha chiesto il caso generale, ma esattamente quel pezzo di software specifico e quel caso specifico che lo fa. La tua risposta non è sbagliata, ma risponde solo a una domanda diversa da quella che OP ha chiesto.
Agent_L

1
Le prime 3 frasi sono ancora per una domanda diversa: "come funziona la compressione delle immagini" - non c'è compressione nella rotazione senza perdita. "Al compressore l'immagine ruotata" - di nuovo, il compressore non viene invocato. "se la compressione è senza perdita" - la compressione è con perdita. La rotazione è senza perdita. Ora, questo è quanto sono disposto a prendere questo argomento. Vedo il tuo punto, sono d'accordo, ma è completamente fuori posto qui. A proposito, anch'io sono un programmatore e ho fatto la mia parte di lettura e scrittura di file grezzi.
Agent_L

1
Ho creato un'immagine in Paint, l'ho ruotata 4 volte ed è identica, ma le dimensioni sono comunque passate da 1,6 a 8,1 KB. Il diff binario mostra che i dati dell'immagine non sono stati toccati, è solo un'enorme quantità di metadati nei <?xpackettag.
Agent_L

1
Se le dimensioni di un JPEG sono divisibile per 8 (o 16 con sottocampionamento), può essere ruotato in incrementi di 90 gradi senza perdita di qualità . La chiave è non decodificarla completamente in RGB, ma lavorare direttamente con i coefficienti DCT. È una funzione specializzata che spesso non è inclusa in un editor di immagini generale. Vedi ad esempio en.wikipedia.org/wiki/Libjpeg#jpegtran . Se hai eseguito l'esperimento con Windows Photo Viewer come specificato nella domanda, vedresti che è effettivamente senza perdita di dati.
Mark Ransom,
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.