Si une image subit une rotation sans perte, pourquoi la taille du fichier change-t-elle?


37

Je cherchais des méthodes de rotation d'image sans perte et je suis tombé sur cette question qui l'explique plutôt bien:

Les rotations de "Windows Photo Viewer" sont-elles sans perte?

J'ai donc créé un fichier JPEG 256 × 256 avec des pixels aléatoires (filtre de nuage de Photoshop), puis je l'ai pivoté à l'aide de Windows Picture Viewer. Après la rotation, la taille du fichier a augmenté, mais uniquement lors de la première rotation. A chaque rotation suivante, la taille du fichier est restée statique. Je sais que la rotation s'effectue sans perte, car je l'ai tournée plusieurs fois sans perte de qualité notable, alors qu'une image 257 × 257 subissant une rotation 20 fois entraînait de lourdes pertes.


8
De combien la taille du fichier a-t-elle augmenté dans vos tests?
James Snell

3
@ JamesSnell Je savais que j'aurais dû inclure cela. Celui que je viens d'utiliser avec le filtre Différences de GIMP était à l'origine de 14 583 octets, mais a été remplacé par 23 638 octets après la rotation. Cela représente une différence de plus de 9 000 octets, ce qui semble être une quantité de données supplémentaires si nous nous intéressons uniquement aux métadonnées.
oscilatingcretin

4
Cela semble être beaucoup de métadonnées supplémentaires. Je ne serais pas trop rapide pour supposer que toutes ces données supplémentaires sont des métadonnées. Il me semble que la différence de taille due aux métadonnées devrait presque être une constante (à quelques octets près pour tenir compte de la représentation sous forme de chaîne de certains nombres).
scottbb

4
Lorsque vous fournissez des informations complémentaires à la question, modifiez-les plutôt que dans les commentaires. Les commentaires sont éphémères et peuvent être nettoyés de temps en temps.
scottbb

2
Le téléchargement de la version originale de votre image de test serait utile.
CodesInChaos

Réponses:


36

Cela est probablement dû au codage par entropie , dernière étape de la compression JPEG sans perte, une fois les données d'image quantifiées afin de réduire leur taille.

Lorsqu'une image JPEG subit une rotation sans perte, cette dernière couche de codage sans perte doit être annulée, les coefficients DCT non empaquetés sont brassés, puis les coefficients mélangés doivent être à nouveau codés en entropie. Étant donné que l'efficacité de la couche de codage entropique dépend de l'ordre des coefficients DCT dans chaque bloc, la rotation de l'image étant modifiée, il ne faut pas s'étonner que le fichier d'image pivoté puisse être inférieur ou supérieur de quelques pour cent à celui d'origine.

L’étape de codage par entropie peut également être réalisée de différentes manières. Il est donc tout à fait possible que la taille du fichier de la même image JPEG varie en fonction du logiciel qui effectue le codage. Certaines des différences potentielles entre les codeurs incluent:

  • choix du codage arithmétique (rare mais potentiellement plus efficace, brevetée auparavant) par rapport au codage de Huffman (plus simple, standard);
  • choix séquentiel (chaque bloc de 8 x 8 pixels est codé un à un) par opposition à progressif (les composantes basse fréquence de tous les blocs sont codées avant les composantes de fréquence supérieure, généralement un peu plus compactes);
  • choix d'utiliser les tables de symboles Huffman standard (plus rapide, plus simple, peut être plus efficace pour les très petites images) par rapport aux tables personnalisées optimisées pour chaque image (généralement plus efficaces pour les grandes images, plus lentes et plus complexes à encoder);
  • Si des tables de Huffman personnalisées sont utilisées, différents encodeurs peuvent potentiellement générer différentes tables pour les mêmes données d'image.
  • divers détails de bas niveau du processus de codage lui-même, tels que l'inclusion éventuelle de marqueurs de redémarrage dans le flux de données, peuvent également varier entre les codeurs.

De plus, les "fichiers JPEG" avec lesquels les gens travaillent normalement contiennent en fait des données d'image compressées au format JPEG, enveloppées dans un conteneur JFIF ou Exif , qui combinent les données d'image avec un ou plusieurs blocs de métadonnées et introduisent leur propre ensemble de complications. Même si le logiciel qui fait pivoter l'image ne modifie pas réellement les métadonnées JFIF / Exif, une simple réorganisation des données peut potentiellement affecter la taille du fichier de quelques octets.

En particulier, les métadonnées JFIF / Exif peuvent contenir une ou plusieurs vignettes de l’image pleine taille, et le logiciel qui fait pivoter les images doit vraiment régénérer (ou également faire pivoter sans perte!) Les vignettes de façon à ce qu’elles correspondent à la nouvelle orientation de l’image complète. image de taille. Cela seul pourrait facilement expliquer la différence de taille observée.


4
Pour une différence de 9 Ko (60%), je suppose que ce sont les vignettes.
BlueRaja - Danny Pflughoeft

Le format JPEG peut être trop simple pour que cela vaille la peine que les codeurs le fassent, mais les codeurs vidéo tels que x264 peuvent en réalité prendre en compte la capacité du codeur d’entrée à coder ce qu’ils sont sur le point de produire en sortie, lorsqu’ils prennent des décisions de compromis taux / distorsion. (c’est-à-dire décider du nombre de bits que chaque alternative pourrait coûter et comparer cela à l’erreur avec perte). Ceci s'appelle la quantification en treillis. Voir Notes sur l’implémentation de la quantification de treillis dans H.264 de l’auteur de x264 (Loren Merritt); il commence par une explication assez basique du but.
Peter Cordes

Quoi qu’il en soit, le codeur JPEG a peut-être choisi les coefficients DCT de telle sorte qu’il soit bien compressé avec le codeur entropique, de sorte que même un compresseur optimal ne puisse pas produire une version tournée aussi petite. (Parce que les placer dans un ordre différent les rendrait probablement moins compressibles.) Ceci serait presque certainement un effet mineur pour JPEG, car chaque bloc 8x8 est codé séparément (réinitialisation de l'état du codeur entropique, autant que je sache). (Les images I en h.264 utilisent la prédiction intra, prédire à partir d'autres blocs dans la même image, ce qui les rend plus petits qu'un JPEG avec la même qualité visuelle.)
Peter Cordes

24

Je suis allé de l'avant et j'ai répété l'expérience pour voir si je pouvais comprendre ce qui se passait.

Procédure

J'ai généré une image RVB aléatoire de 256 x 256 pixels à l'aide du filtre "Bruit solide" de GIMP (Filtres> Rendu> Nuages> Bruit plein ...) à l'aide des paramètres par défaut (indiqués ci-dessous):

entrez la description de l'image ici

Et le résultat:

entrez la description de l'image ici

Ensuite, j'ai enregistré l'image au format JPEG en utilisant les paramètres par défaut:

entrez la description de l'image ici

Ensuite, j'ai transféré l'image vers Windows et l'a ouverte avec la visionneuse de photos Windows en cliquant avec le bouton droit de la souris sur l'image dans l'explorateur de fichiers et en choisissant Aperçu dans le menu. Ensuite, j'ai fait pivoter l'image à l'aide des boutons situés en bas, puis j'ai sauvegardé l'image en naviguant jusqu'à l'image suivante à l'aide des touches fléchées.

Pour chacun des tests ci-dessous, j'ai commencé avec une copie de l'image d'origine, puis pivoté (cliqué sur le bouton de rotation) le nombre de fois correspondant avant l'enregistrement. Voici les tailles reslting ( 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

Observations immédiates

  • Windows Photo Viewer (WPV) augmente considérablement la taille; la quantité d'augmentation est environ quatre fois dans ce test!
  • Toutes les nouvelles images augmentent à peu près à la même taille, mais elles ne sont pas identiques.
  • WPV ne ré-encode pas et ne ré-enregistre pas l'image quand elle est tournée par un multiple de 360 ​​degrés. (L'horodatage, 11:27, correspond à la première copie des fichiers.)

Utiliser des cmp -lfichiers qui doivent avoir un contenu identique nous permet de voir où les fichiers diffèrent.

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

Ces fichiers ne diffèrent que par quatre octets (en fait, un horodatage), ce qui signifie que WPV fait la même chose à chaque fois; il ne reste plus qu'à comprendre ce que c'est.

Observations détaillées

Pour cela, j'ai utilisé JPEGsnoop pour voir ce qui était exactement dans les images.

Comme les sorties sont assez longues, je les ai liées comme un élément essentiel . Voici un résumé des différences:

  • GIMP utilise uniquement un segment APP0(JFIF) et COM(commentaire) pour les métadonnées. WPV laisse le APP0segment intact, mais ajoute curieusement un octet nul au commentaire (de sorte qu'il se termine à zéro).

  • WPV ajoute deux APP1segments, qui sont des métadonnées Exif et XMP. Ces segments sont respectivement 4286 et 12726 octets. Ensemble, ils représentent presque toute l'augmentation de la taille du fichier.

  • GIMP produit un JPEG progressif, tandis que WPV produit un JPEG de base (non progressif). Pour cette raison, l'image de GIMP comporte plusieurs segments de numérisation, tandis que l'image WPV n'en contient qu'un. D'après mon expérience, l'image progressive est parfois légèrement plus petite.

  • GIMP a utilisé un sous-échantillonnage de chrominance 1 × 1, alors que le PVP a utilisé un sous-échantillonnage de 2 × 2. Cela me porte à penser que le WPV n'utilise pas la "vraie" rotation sans perte, sauf s'il est en mesure de détecter cette image en noir et blanc.

Pour résoudre ces problèmes, j'ai effectué un deuxième test.

Procédure

J'ai suivi des étapes similaires au premier test. J'ai créé une image aléatoire 256 × 256 RVB à l'aide du filtre de bruit RVB (Filtres> Nez> Nez RVB ...) avec les paramètres suivants:

entrez la description de l'image ici

Voici le résultat:

entrez la description de l'image ici

J'ai exporté le fichier au format JPEG en utilisant les paramètres suivants:

entrez la description de l'image ici

Progressif a été désactivé, mais le sous - échantillonnage est toujours réglé sur 4: 4: 4 (ce qui correspond à un autre nom pour le sous-échantillonnage 1 × 1). La qualité est augmentée à 98.

J'ai copié l'image et fait pivoter la copie dans le sens des aiguilles d'une montre; puis copié la version tournée et cette copie tournée dans le sens antihoraire, afin que nous puissions comparer directement la qualité entre la copie originale et la copie traitée par WPV.

Résultats

-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

Bien que l’augmentation cette fois-ci soit plus faible en termes relatifs (environ 40%), l’augmentation absolue est encore plus importante - environ 62 kB. Cela suggère que WMV utilise un encodage moins efficace.

J'utiliserai ImageMagick pour comparer les deux images:

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

Il n'y a pas de pixels différents entre l'original et la copie pivotée. Ainsi, même si WPV n’utilise pas la "vraie" rotation sans perte, il fait un travail suffisant. Je suppose que je sais ce qui se passe, et pour vous expliquer, je vais m'étendre un peu sur le calcul derrière la compression JPEG.

L'algorithme de compression JPEG divise une image en blocs de 8 × 8 pixels. Chacun de ces blocs est ensuite soumis à une transformée en cosinus discrète (DCT) . Les coefficients DCT résultants décrivent le bloc comme une somme d'ondes de fréquences différentes. L'algorithme "jette" ensuite dans les ondes haute fréquence des informations correspondant à du bruit et à des détails très fins. Le processus de décodage inverse le DCT, en additionnant les ondes stockées pour récupérer le bloc.

Il est possible de faire pivoter les "ondes" du DCT sans annuler ni refaire la transformation (en gros, vous transformez toutes les ondes horizontales en ondes verticales et vice-versa). Ce que je pense en WPV, c'est que l'image est réellement décodée, tournée, puis ré-encodée. Au cours du processus de réencodage, la taille de notre image étant un multiple de 8 dans les deux dimensions, chacun des nouveaux blocs correspond à l'un des blocs d'origine. Il est important de noter que chaque bloc n’ayant pas de composants haute fréquence, l’algorithme ne jette aucune information et trouve exactement les bons composants DCT qu’aurait une "vraie" rotation sans perte.

Enfin, je regarderai de nouveau les composants des fichiers JPEG. Les résultats sont à nouveau liés comme des gists . En comparant les deux:

  • L'image WPV contient 4286 + 2 octets supplémentaires de métadonnées Exif, 1 octet supplémentaire dans le commentaire et 12 726 + 2 octets de métadonnées XMP. Cela représente un total de 17 017 octets de métadonnées supplémentaires. A quoi servent toutes ces données? J'ai jeté un coup d'œil dans le dossier avec mon fidèle éditeur d'hex et une copie des normes pertinentes:

    • Les métadonnées Exif sont structurées comme une image TIFF, qui contient un certain nombre de balises (il y a beaucoup plus de complexité, mais je vais passer directement dessus). La plupart des octets du segment Exif sont contenus dans deux balises identiques avec un numéro de balise EA1C(59 932 décimal). Ce numéro d'étiquette n'est pas documenté partout où j'ai pu trouver. Les deux balises contiennent 2060 octets de type "indéfini", qui sont tous des octets nuls, à l'exception des six premiers ( 1C EA 00 00 00 08). Je n'ai aucune idée de ce que sont ces balises, pourquoi il y en a deux et pourquoi elles doivent être de 2 ko chacune.

    • Les métadonnées XMP sont en réalité un document XML incorporé complet avec un espacement de nom et de longs UUID, qui ne contient que la chaîne de version WPV (qui figurait déjà dans les métadonnées Exif). Cependant, cela ne représente qu'environ 400 octets. Le reste du segment comprend 122 répétitions de 100 espaces suivies d'une nouvelle ligne . C'est plus de 12 000 octets d'espace totalement perdu.

  • Comme le test précédent, GIMP et WPV utilisent les mêmes tables de quantification DCT. Cela signifie qu'ils doivent calculer exactement les mêmes coefficients DCT, ce qui explique pourquoi les images sont exactement les mêmes. Je ne sais pas si WPV utilise les mêmes tables de quantification ou s'il les copie à partir de l'entrée.

  • Contrairement au test précédent, cette fois, le WPV utilise un sous-échantillonnage 1 × 1, de sorte qu'il peut effectivement détecter qu'il s'agit d'une image couleur (ou du moins que des échantillons plus élevés sont nécessaires pour réencoder l'image sans perte).

  • GIMP et WPV utilisent différentes tables de Huffman (partie de l'étape de codage par entropie). Les tables pour WPV sont plus grandes de 279 octets au total et contiennent dans un cas 7 fois plus de codes.

    En examinant les statistiques de JPEGsnoop, on constate que certains de ces codes sont rarement utilisés. Par exemple, dans le ID: 1, Class: ACtableau, sur les 119 codes 16 bits définis, seuls 23 sont réellement utilisés. Globalement, le segment de numérisation réel est 28,5% plus grand dans la version WPV.

Sommaire

  • Le WPV ne fait peut-être pas de "vraies" rotations sans perte, mais les rotations semblent être pratiquement sans perte.

  • La taille supplémentaire est due en partie à une quantité fixe de métadonnées ajoutées et en partie à un codage par entropie moins efficace.

Information sur la version:

  • 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
    
  • OS (Windows):

    entrez la description de l'image ici

  • GIMP (Linux): 2.8.14 (à partir du paquet gimp, version 2.8.14-1+deb8u1)

    entrez la description de l'image ici

  • Visionneuse de photos Windows (selon les métadonnées de l'image):

    Microsoft Windows Photo Viewer 10.0.10586.0
    

20

EDIT : Cette réponse a été postée avant que je sache que la taille des fichiers avait augmenté d’environ 9 Ko (9055 octets pour l’image 256 × 256, 9612 Ko pour l’image 512 × 512).

Très probablement, lors de la première rotation de l'image, Windows Picture Viewer a effectué l'une des opérations suivantes (ou les deux):

  1. Ajout d'une balise EXIF ​​qui ne figurait pas dans l'image JPEG d'origine (peut-être la balise Orientation);
  2. Informations modifiées / ajoutées à une balise qui existait déjà (par exemple, balises Logiciel de traitement ou Logiciel de traitement d'image).

Cela a augmenté la taille du fichier en raison de la balise EXIF ​​supplémentaire (et / ou des données supplémentaires des balises existantes).

Les rotations suivantes n'augmentaient pas la taille du fichier car toutes les balises et / ou données de balises que WPV aurait ajoutées / modifiées étaient déjà présentes. Seule la valeur de la balise d' orientation a changé (et peut-être aussi les valeurs de la balise de date / heure).


EDIT : Il est presque certain que cette explication ne peut pas représenter environ 9 Kio de données supplémentaires dans le fichier. En outre, en l’absence de toute autre raison de l’augmentation de la taille, cette explication s’attendrait à ce que l’augmentation de la taille soit plus ou moins constante (modulo certaines différences de longueur entre les représentations sous forme de chaîne de données numériques, probablement quelques octets). Ce n'est évidemment pas ce qui se passe ici, du moins pas l'explication complète.


1
Et une balise EXIF ​​va prendre 9 Ko? Eh bien, au moins, cela est facile à tester - demandez à l’opérateur de supprimer les balises EXIF ​​ou autres de l’image pivotée et de voir comment la taille du fichier change.
Carl Witthoft

2
@CarlWitthoft 9kB est une nouvelle information. Editer pour le mentionner.
scottbb

3

Sans le reverse engineering jpeg en / décodeur, il est impossible de dire avec certitude. Il existe en fait un certain nombre de normes JPEG et contrairement à la croyance populaire, toutes ne peuvent pas être modifiées sans recodage.

Il est possible que la première sauvegarde soit une réécriture avec perte dans sa version préférée du fichier jpeg et que les rotations suivantes constituent un simple ajustement de métadonnées ou une opération directement sur la table DCT (ce qui est possible pour certains schémas de codage).

L'augmentation de la taille du fichier peut également inclure des métadonnées supplémentaires, bien que 9k semble beaucoup, c'est possible. L’augmentation peut également être expliquée par l’ajout d’une vignette qui n’était peut-être pas présente dans le résultat de GIMP. Nous pourrons peut-être obtenir plus d'informations directement dans les fichiers (avant et après le VPP).

Dans tous les cas, essayer de travailler sans perdre avec jpeg est vraiment une course pour duper, car ce n’est utile que pour certaines tailles d’image, tous les décodeurs et encodeurs ne sont pas identiques et il est nécessaire que ces éditeurs travaillent directement avec le contenu jpeg sur lequel vous ne pouvez pas compter. le cas ... Ce n’est pas parce qu’il le fait maintenant que cela continuera dans le futur.

Votre meilleur pari est de travailler avec un format sans perte et d’éviter complètement la douleur.


2
Je ne suis pas du tout convaincu que la rotation des données jpeg devrait en premier lieu provoquer un ré-encodage.
Carl Witthoft

Cela dépend si vous êtes programmeur ou non ... Je suppose que vous ne l'êtes pas. Vous devez être spécifiquement à la recherche de cette optimisation pour effectuer cette modification minimale, sinon une opération de sauvegarde commencerait à partir du bitmap non compressé.
James Snell

3
La question liée indique clairement que la Visionneuse de photos Windows effectue la rotation des fichiers JPEG sans perte.
vclaw

2
@ James Je ne suis pas un programmeur de bas niveau, même si je joue à la télévision :-). Le PO fournissait un lien vers une description précise du moment où il y aurait un recodage et du moment où il ne le serait pas. J'avais déduit de cette discussion qu'il n'avait tourné que de $ \ frac {\ pi} {2} $. Je conviens que la rotation angulaire arbitraire provoque un réencodage et qu’il va en résulter une perte d’informations à moins que l’image X-by-Y ne soit incorporée dans une région au moins aussi grande que l’hypoténuse.
Carl Witthoft

1
Nous sommes pratiquement certains que nous savons que le format WPV tourne de manière réversible pour les images dont les dimensions sont multiples de 8/16. Voir le commentaire de @ Tristan concernant la réponse de Matt Grum à la question liée au PO. Tristan a travaillé sur l'équipe WPV chez Microsoft, et le confirme essentiellement.
scottbb

1

La rotation JPEG sans perte est possible uniquement sans introduction d'artefacts de limite si les dimensions de l'image sont des multiples de la taille du bloc (généralement [/ toujours?] 8). Reportez - vous à la page de manuel jpegtran (désolé, je n’ai pas un bon lien canonique pour le faire; n'hésitez pas à le modifier si vous en trouvez un) pour plus de détails sur ce qui est impliqué:

La transformation de transposition n'a aucune restriction concernant les
dimensions de l' image . Les autres transformations fonctionnent plutôt étrangement si les dimensions de l'image ne sont pas un multiple de la taille de l'iMCU (généralement 8 ou 16 pixels), car elles ne peuvent transformer que des blocs complets de données de coefficients DCT de la manière souhaitée.

Le comportement par défaut de jpegtran lors de la transformation d'une image impaire
est conçu pour préserver la réversibilité exacte et la
cohérence mathématique de l'ensemble de transformations. Comme indiqué, la transposition est
capable de retourner toute la zone de l'image. La mise en miroir horizontale laisse toute colonne iMCU partielle sur le bord droit intacte, mais est capable de retourner toutes les lignes de l'image. De la même manière, la mise en miroir verticale laisse intacte toute ligne partielle d'iMCU sur le bord inférieur, mais est capable d'inverser toutes les colonnes. Les autres transformations peuvent être construites sous forme de séquences d'opérations de transposition et de retournement; par souci de cohérence, leurs actions sur les pixels de contour sont définies comme étant identiques au résultat final de la séquence transpose-flip correspondante.

Pour une utilisation pratique, vous préférerez peut-être supprimer les
pixels de bord non transformables plutôt que de disposer d'une bande d'aspect étrange le long des
bords droit et / ou inférieur d'une image transformée. Pour ce faire, ajoutez le commutateur -trim:

Je suppose que la visionneuse de photos de Windows évite ce problème en effectuant une décompression et une recompression de très haute qualité afin de simuler un comportement sans perte lorsque les dimensions de l'image ne sont pas des multiples de 8, plutôt que d'effectuer une rotation sans perte. Un bon utilitaire ferait juste sans perte réelle, artefacts et tout, ou déposerait quelques pixels, plutôt que de ruiner la qualité de l'image entière (et d'augmenter la taille du fichier).


1
non pertinent pour une image 256x256.
le

J'ai mal lu et pensé que le problème était pour la version 257x257.
R ..

0

Je n'ai pas de réponse précise, mais quelques théories possibles sur les raisons. Certains types de fichiers fonctionnent de telle manière que deux codes différents pour une image de ce type ne produisent pas nécessairement des images différentes. Par exemple, le type de fichier PNG fonctionne de cette manière car il permet un arrière-plan transparent mais une image avec un arrière-plan transparent et identique, à la différence que le même arrière-plan est blanc apparaît exactement de la même manière. Un fichier image est dit compressé s'il occupe moins de 3 octets de mémoire par pixel. Je crois que sauf ceux avec un arrière-plan transparent, aucun fichier PNG ne génère exactement la même image. Chaque fois que vous enregistrez une image au format PNG, celle-ci est convertie en un code qui génère l'image d'origine. Sauf pour les images très inhabituelles, par exemple, chaque pixel est une couleur aléatoire de toutes les 2 ^ 24 couleurs. le code utilisera moins de mémoire que 3 octets par pixel, ce qui fait que la sauvegarde en PNG est une compression sans perte. Par contre, pour économiser de la mémoire, seules certaines images peuvent être générées par le code d’un fichier image JPEG. Il existe probablement plus d'un type de fichier JPEG et je ne sais pas si l'un d'entre eux possède la propriété telle que deux images différentes de ce type de fichier peuvent générer exactement la même image. Je suppose que plusieurs fois, vous avez simplement fait pivoter une image, puis vous l'avez enregistrée au format JPEG. Vous expliquerez ainsi ce qui s'est passé, en supposant que c'est ce que vous avez fait, ce que je ne sais pas si c'est vrai. Une rotation que vous avez effectuée est sans perte s'il existe un moyen de récupérer le même code de fichier image que celui que vous aviez avant de le faire pivoter et de le sauvegarder. Vous avez peut-être tort de dire que vous avez réellement effectué une rotation sans perte. Si c'était vraiment sans perte,


-3

Les raisons derrière ceci sont quelques

la manière dont les images sont codées et compressées changera la taille simplement à cause de l'algorithme de compression. vous pouvez le tester en l'enregistrant sous forme de bitmap, puis en le faisant pivoter. Dans ce format ou tout autre format brut, la taille doit rester la même. Si ce n'est pas le cas, le programme qui enregistre l'image ajoute de nouvelles données, éventuellement des métadonnées ou quelque chose d'autre.

Mais pourquoi faites-vous tourner un jpeg 20 fois?


2
Si vous lisez le lien dans la question initiale, du moins pour Windows Picture Viewer , si les dimensions d'un fichier JPEG sont un multiple de 8, les rotations de JPEGS dans WPV sont des transformations sans perte. Un moyen simple de le tester consiste à effectuer une rotation de 4 fois (avec la même orientation que l'original) et à effectuer une simple soustraction d'image pixel par pixel.
scottbb

@scottbb Ce n'est pas nécessairement un problème avec la visionneuse d'images Windows. Tout ce qui fait pivoter un format avec perte doit recalculer la compression. faire pivoter une image par multiples de 8 signifie que tout rentre dans des mots de 8 bits et ne peut pas être compressé de manière à ajouter des artefacts. Ceci est basé sur le fonctionnement de l'algorithme et est implémenté dans le programme utilisé.
Cc Dd

-3

En raison de la compression des images . Tous les formats tels que PNG ou JPG en général ne conservent pas la taille du fichier après la rotation.

Pour le compresseur, l'image pivotée est simplement une image différente. En raison du fonctionnement de l'heuristique de compression, rien ne garantit qu'il compressera une image pivotée de la même manière .

Bien sûr, si la compression est sans perte, si vous faites pivoter l'image 4 fois la 4ème fois, l'image est à nouveau identique (tournée jusqu'à ce qu'elle devienne inclinée à l'origine): dans ce cas, elle devrait redevenir de la même taille compressée, sinon c'est pour l'une des raisons suivantes :

  • Ajout de métadonnées : le programme a ajouté un morceau de texte pour une raison quelconque
  • Le compresseur a changé: le programme peut choisir de simplement ré-enregistrer l'image en tant qu'original s'il n'y a pas de modification, mais si vous appliquez une modification (même 4 rotations à 90 degrés), il peut décider de recompresser l'image à l'aide de la sienne. compresseur (le programme ne sait plus que c'est toujours la même image).
  • En général, le même compresseur (libPNG ou libJPG) donne des résultats très différents selon les implémentations, les versions de la même bibliothèque et les paramètres de compression (avec le même système d'exploitation et le compilateur, parfois aussi).

La compression d'image consiste à compresser les images en morceaux de 4x4 ou d'autres tailles. En général, un compresseur considère une image pivotée comme une image différente. Toutefois, comme un bloc de pixels compressé est juste une décomposition linéaire, si les blocs de l’image sont identiques, il est possible de simplement transposer / reproduire en miroir les matrices de décomposition linéaire en conservant le même qualité:

Notez que ceci doit être implémenté sur une base individuelle , ce qui explique également l'augmentation initiale de la taille => lors de la première rotation, il essaye simplement de compresser l'image en morceaux qui sont rotatifs:

  • Sinon, la qualité de l’image se dégrade.
  • Si elle réussit, elle n’augmente la taille qu’une seule fois, alors chaque rotation conserve la même qualité.

  • Cette opération ne réussit que si l'image est créée par morceaux égaux. (la taille de l'image est multiple de celle du bloc).

Le scottbb répond mal et vous pouvez faire un test simple:

  • Ouvrez l'image originale: Screenshot it
  • Faites pivoter l'image 4 fois avec WPV: Capturez-le
  • Comparez les 2 captures d'écran

Vous verrez l'image modifiée (elle est recomprimée lors de la première rotation). Toutefois, ce changement étant limité dans le temps, vous pouvez maintenant le faire pivoter à nouveau sans perte de qualité (si la taille de l'image est un multiple de 8).

Pour répondre directement à OP:

Je sais que ça tourne sans perte

Non, ce n’est pas une rotation sans perte, mais une perte de qualité au moins une fois (lors de la première rotation: car il faut d’abord la compresser de manière à ce qu’elle puisse être tournée), puis sa qualité est préservée.


1
La question concerne la rotation sans perte, évitant ainsi la recompression.
Agent_L

5
OP a posé la question non pas sur le cas général, mais sur ce logiciel et ce cas particulier. Votre réponse n'est pas fausse, elle répond simplement à une question différente de celle posée par OP.
Agent_L

1
Les 3 premières phrases posent toujours une question différente: "comment fonctionne la compression d'images" - il n'y a pas de compression dans la rotation sans perte. "Pour le compresseur l'image tournée" - encore une fois, le compresseur n'est pas appelé. "si la compression est sans perte" - la compression entraîne des pertes. La rotation est sans perte. Maintenant, voici à quel point je suis prêt à prendre cet argument. Je vois ce que vous voulez dire, je suis d’accord avec cela, mais c’est complètement hors de propos ici. BTW, je suis aussi un programmeur et j'ai fait ma part de lecture et d'écriture de fichier brut.
Agent_L

1
J'ai créé une image dans Paint, je l'ai pivotée 4 fois et elle est identique, mais sa taille est néanmoins passée de 1,6 à 8,1 Ko. Les différences binaires montrent que les données d'image n'ont pas été modifiées, c'est simplement une énorme quantité de métadonnées dans les <?xpacketbalises.
Agent_L

1
Si les dimensions d'un fichier JPEG sont divisibles par 8 (ou 16 avec sous-échantillonnage), vous pouvez effectuer une rotation par incréments de 90 degrés sans perte . La clé est de ne pas tout décoder en RVB, mais de travailler directement avec les coefficients DCT. C'est une fonction spécialisée qui n'est pas souvent incluse dans un éditeur d'image général. Voir par exemple en.wikipedia.org/wiki/Libjpeg#jpegtran . Si vous avez effectué votre test avec la Visionneuse de photos Windows comme indiqué dans la question, vous constaterez que cette opération est sans perte.
Mark Ransom
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.