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):
Et le résultat:
Ensuite, j'ai enregistré l'image au format JPEG en utilisant les paramètres par défaut:
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 -l
fichiers 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 APP0
segment intact, mais ajoute curieusement un octet nul au commentaire (de sorte qu'il se termine à zéro).
WPV ajoute deux APP1
segments, 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:
Voici le résultat:
J'ai exporté le fichier au format JPEG en utilisant les paramètres suivants:
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: AC
tableau, 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):
GIMP (Linux): 2.8.14 (à partir du paquet gimp
, version 2.8.14-1+deb8u1
)
Visionneuse de photos Windows (selon les métadonnées de l'image):
Microsoft Windows Photo Viewer 10.0.10586.0