Pourquoi ces méthodes de compression (sans perte) de nombreuses images png similaires sont-elles inefficaces?

21

Je viens de rencontrer la chose suivante: j'ai mis plusieurs copies identiques d'une image png dans un dossier, puis j'ai essayé de compresser ce dossier avec les méthodes suivantes:

  • tar czf folder.tar.gz folder/
  • tar cf folder.tar folder/ && xz --stdout folder.tar > folder.tar.xz (celui-ci fonctionne bien pour des images identiques, cependant pour des images similaires le gain est nul)
  • zip -r folder.zip folder/

Lorsque j'ai vérifié la taille du .tar.gz, .tar.xz, .zipje me suis aperçu qu'il est presque le même que celui de folder/.
Je comprends qu'une image png elle-même peut avoir un niveau de compression élevé et ne peut donc pas être compressée davantage. Cependant, lors de la fusion de nombreuses images png similaires (dans ce cas, même identiques) dans une archive, puis en compressant l'archive, je m'attends à ce que la taille requise diminue considérablement. Dans le cas d'images identiques, je m'attendrais à une taille à peu près la taille d'une seule image.

un invité
la source
2
Ce comportement n'est présent qu'avec les fichiers png?
pdexter
7
Ne pas en faire une réponse car il répond à une question non posée, mais si vous savez que vous allez compresser de nombreuses images presque identiques, vous pouvez toujours remplacer toutes les images sauf la première par un diff binaire par rapport à la première image. En supposant que l'image n'est pas bruyante, vous obtiendrez des sorties très compressibles et les images originales seront toujours reproductibles.
Baldrickk
Si vous utilisez des fichiers non compressés (par exemple .bmp), le fichier tar.gz devrait pouvoir profiter de la similitude. (Au moins si la similitude est que beaucoup de pixels sont identiques)
CodesInChaos
1
Je n'en sais rien, mais selon Wikipedia, le format d'archive "ZPAQ" prend en charge la déduplication, ce qui, je crois, est ce que vous recherchez. en.wikipedia.org/wiki/ZPAQ#Deduplication
coneslayer
Vous essayez de compresser quelque chose qui est déjà compressé. Voir ici
Kyle Khalaf

Réponses:

34

Jetez un œil au fonctionnement des algorithmes de compression. Au moins, ceux de la famille Lempel-Ziv ( gzip utilise LZ77 , zipsemble - t- il aussi le plus souvent , et xz utilise LZMA ) se compressent quelque peu localement : les similitudes éloignées les unes des autres ne peuvent pas être identifiées.

Les détails diffèrent entre les méthodes, mais en fin de compte, au moment où l'algorithme atteint la deuxième image, il a déjà «oublié» le début de la première. Etc.

Vous pouvez essayer de modifier manuellement les paramètres de la méthode de compression; si la taille de la fenêtre (LZ77) resp. la taille des blocs / morceaux (méthodes ultérieures) est au moins aussi grande que deux images, vous verrez probablement une compression supplémentaire.


Notez que ce qui précède ne s'applique vraiment que si vous avez des images identiques ou des images non compressées presque identiques . S'il y a des différences, les images compressées peuvent ne pas se ressembler en mémoire. Je ne sais pas comment fonctionne la compression PNG; vous souhaiterez peut-être vérifier manuellement les représentations hexadécimales des images que vous avez pour les sous-chaînes partagées.

Notez également que même avec des paramètres modifiés et une redondance à exploiter, vous n'obtiendrez pas la taille d'une image. Des dictionnaires plus grands signifient une plus grande taille de mot de code, et même si deux images sont exactement identiques, vous devrez peut-être coder la seconde en utilisant plusieurs mots de code (qui pointent dans la première).

Raphael
la source
3
Une réponse plus précise: gzip et zip utilisent le même codec DEFLATE sous-jacent, qui est basé sur la théorie LZ77 + Huffman.
Nayuki
Ouaip! C'est la moitié de l'histoire; voir ma réponse pour l'autre moitié, ou la grande réponse de Nayuki .
DW
1
pour la postérité: formats d'archives qui exploitent les redondances entre les fichiers en concaténant les fichiers en un seul blob et en les compressant qui sont appelés solides . Je ne sais pas s'il existe d'autres termes pour les niveaux intermédiaires de «solidité», etc.
underscore_d
22

Pourquoi cela se produit. Il y a en fait deux effets différents qui se produisent ici:

  • Chaque fichier compressé indépendamment. Certains programmes d'archivage - y compris zip - compressent chaque fichier indépendamment, sans mémoire d'un fichier à un autre. En d'autres termes, chaque fichier est compressé séparément, puis les fichiers compressés sont concaténés dans une archive.

  • Mémoire à court terme. Certains programmes d'archivage peuvent utiliser des informations sur un fichier pour mieux compresser le fichier suivant. Ils concaténent efficacement les fichiers, puis compressent le résultat. C'est une amélioration.

    Voir aussi la réponse de Nayuki pour plus de discussion à ce sujet.

    Cependant, il y a un deuxième problème. Certains schémas de compression - y compris zip, gzip et bzip2 - ont une mémoire limitée. Ils compressent les données à la volée et se souviennent des 32 Ko de données passés, mais ils ne se souviennent de rien des données qui se sont produites beaucoup plus tôt dans le fichier. En d'autres termes, ils ne peuvent pas trouver de données en double si les doublons se produisent à plus de 32 Ko d'intervalle. Par conséquent, si les fichiers identiques sont courts (plus courts que 32 Ko environ), l'algorithme de compression peut supprimer les données dupliquées, mais si les fichiers identiques sont longs, l'algorithme de compression est arrosé et devient sans valeur: il ne peut détecter aucun des éléments suivants: le doublon dans vos données. (Bzip se souvient des 900 derniers Ko environ des données, au lieu de 32 Ko.)

    Tous les algorithmes de compression standard ont une taille de mémoire maximale, au-delà de laquelle ils ne parviennent pas à détecter les modèles ... mais pour certains, ce nombre est beaucoup plus grand que d'autres. Pour Bzip, c'est quelque chose comme 900 Ko. Pour xz, c'est quelque chose comme 8 Mo (avec les paramètres par défaut). Pour 7z, c'est quelque chose comme 2 Go. 2 Go est plus que suffisant pour reconnaître les copies dupliquées de fichiers PNG (qui sont généralement beaucoup plus petites que 2 Go). De plus, 7z essaie également d'être intelligent pour placer des fichiers susceptibles d'être similaires les uns à côté des autres dans l'archive, pour aider le compresseur à mieux fonctionner; tar n'en sait rien.

    Voir aussi la réponse de Raphaël et la réponse de Nayuki pour plus d' explications de cet effet.

Comment cela s'applique à votre paramètre. Pour votre exemple spécifique, vous travaillez avec des images PNG. Les images PNG sont elles-mêmes compressées, vous pouvez donc considérer chaque fichier PNG comme une séquence d'octets d'aspect aléatoire, sans motif ni duplication dans le fichier. Il n'y a rien à exploiter pour un compresseur s'il regarde une seule image PNG. Ainsi, si vous essayez de compresser un seul fichier PNG (ou de créer une archive zip / tar / ... contenant un seul fichier PNG), vous n'obtiendrez aucune compression.

Voyons maintenant ce qui se passe si vous essayez de stocker plusieurs copies du même fichier PNG:

  • Petits fichiers. Si le fichier PNG est très petit, tout sauf le zip fonctionnera très bien. Zip échouera de façon spectaculaire: il comprime chaque fichier indépendamment, il n'a donc aucune chance de détecter la redondance / duplication entre les fichiers. De plus, comme il essaie de compresser chaque fichier PNG, il n'obtient aucune compression; la taille d'une archive zip sera énorme. En revanche, la taille d'une archive tar (qu'elle soit compressée avec gzip, bzip2 ou xz) et une archive 7z sera petite, car elle stocke essentiellement une copie du fichier et remarque ensuite que les autres sont toutes identiques - elles bénéficient de conserver la mémoire d'un fichier à un autre.

  • Fichiers volumineux. Si le fichier PNG est volumineux, alors seulement 7z fonctionne bien. En particulier, zip continue d'échouer de façon spectaculaire. De plus, tar.zip et tar.bzip2 échouent gravement, car la taille du fichier est plus grande que la fenêtre de mémoire du compresseur: lorsque le compresseur voit la première copie du fichier, il ne peut pas la réduire (car il a déjà été compressé ); au moment où il commence à voir le début de la deuxième copie du fichier, il a déjà oublié les séquences d'octets vues au début du premier fichier et ne peut pas établir la connexion que ces données sont en fait un doublon.

    En revanche, tar.xz et 7z continuent de bien fonctionner avec plusieurs copies d'un grand fichier PNG. Ils n'ont pas la limitation "petite taille de mémoire" et sont capables de remarquer que la deuxième copie du fichier est identique à la première copie, donc il n'est pas nécessaire de le stocker une deuxième fois.

Que pouvez-vous y faire? Utilisez 7z. Il a un tas d'heuristiques qui aideront à détecter des fichiers identiques ou similaires et à compresser très bien dans ce cas. Vous pouvez également regarder lrzip avec la compression lzop.

Comment puis-je savoir? J'ai pu le vérifier en essayant quelques expériences avec 100 copies d'un fichier contenant des octets aléatoires. J'ai essayé 100 copies d'un fichier de 4 Ko, 100 copies d'un fichier de 1 Mo et 100 copies d'un fichier de 16 Mo. Voici ce que j'ai trouvé:

Size of file      Size of compressed archive (with 100 copies)
                  zip  tar.gz  tar.bz2  tar.xz    7z
         4KB    414KB     8KB     10KB     5KB    5KB
         1MB    101MB   101MB    101MB     1MB    2MB
        16MB    1.6G    1.6GB    1.6GB   1.6GB  401MB

Comme vous pouvez le voir, le zip est horrible, quelle que soit la taille de votre fichier. 7z et xz sont tous les deux bons si vos images ne sont pas trop grandes (mais xz sera fragile et dépendra de l'ordre dans lequel les images seront placées dans l'archive, si vous avez des doublons et des non-doublons mélangés ensemble). 7z est sacrément bon, même pour les gros fichiers.

Les références. Cela est également bien expliqué dans un tas de messages sur Super User. Regarde:

DW
la source
5
Il convient également de garder à l'esprit que le format ZIP a été conçu vers 1990 (PKZIP a introduit le format ZIP en 1989, dit Wikipedia, et DEFLATE a été introduit en 1993). Au cours de cette période, un PC raisonnablement commun pourrait être un 286 ou 386 (le 486 a été introduit en 1989, mais comme toujours, il a fallu un certain temps pour comprendre) fonctionnant sous DOS avec peut-être 2-4 Mo de RAM, seulement peut-être 400- 500 KB dont était directement utilisable sans support de programmation intelligent (EMS, XMS) pour lequel il n'était pas garanti d'être disponible. Dans cet environnement, une petite taille de fenêtre de compression était à peu près une exigence.
un CVn du
"Chaque fichier compressé indépendamment" - Cela semble varier énormément entre les normes et les outils. Mon expérience avec le logiciel de packaging par défaut d'Ubuntu est qu'il semble tout décompresser lors de l'ouverture d'une archive. J'ai souvent pensé qu'il devrait compresser chaque fichier indépendamment, car les gains de convivialité l'emportent généralement sur les inconvénients de la compression.
Raphael
"100 copies d'un fichier contenant des octets aléatoires" - qu'en est-il des fichiers "similaires"? (Vers la question réelle, dans quelle mesure les images PNG sont- elles similaires?)
Raphael
Raphael a fait une bonne remarque à ce sujet dans sa réponse. En fait, j'ai beaucoup d'images similaires (pas identiques) que je veux stocker. Semblables en ce qu'ils montrent la même structure avec de légères variations (également en ce qui concerne l'intensité et le fond). Cependant, les différences sont si petites qu'elles sont à peine visibles. Je les ai essayées tarpuis compressées avec xz(ce qui fonctionnait très bien pour des images identiques) mais en cas d'images similaires le gain est nul. J'ai essayé avec 71 images ayant chacune une taille de ~ 831 Ko.
a_guest
2
@a_guest - ça ne va pas bien se passer. Les images PNG d'aspect similaire auront un contenu d'octets très différent (en raison de la compression PNG). Voir aussi superuser.com/q/730592/93541 , superuser.com/q/418286/93541 , superuser.com/q/893206/93541 , superuser.com/q/921140/93541 - en gros, il n'y a pas de bonnes solutions.
DW
10

Tout d'abord, notez que le format d'image PNG est essentiellement des pixels RVB bruts (avec un certain filtrage de la lumière) poussés à travers le format de compression DEFLATE. De manière générale, les fichiers compressés (PNG, JPEG, MP3, etc.) ne verront aucun avantage à être à nouveau compressés. Donc, pour des raisons pratiques, nous pouvons traiter votre fichier PNG comme des données aléatoires incompressibles pour le reste de l'expérience.

Deuxièmement, notez que les formats ZIP et gzip utilisent également le codec DEFLATE. (Cela expliquerait pourquoi le zippage par rapport au gzipping d'un seul fichier produira essentiellement la même taille de sortie.)


Permettez-moi maintenant de commenter chaque cas de test individuellement:

  • tar czf folder.tar.gz folder/

    Cela crée un fichier TAR (non compressé) qui concatène tous vos fichiers PNG identiques (avec une petite quantité de métadonnées et de remplissage ajoutés). Ensuite, ce fichier unique est envoyé via le compresseur gzip pour créer un fichier de sortie compressé.

    Malheureusement, le format DEFLATE ne prend en charge qu'une fenêtre de dictionnaire LZ77 de 32 768 octets. Donc, même si le TAR contient des données répétitives, si votre fichier PNG est supérieur à 32 Ko, le compresseur DEFLATE ne peut certainement pas se souvenir des données suffisamment loin pour profiter du fait que des données identiques sont récurrentes.

    En revanche, si vous réessayez cette expérience avec, par exemple, un fichier PNG de 20 Ko dupliqué 10 fois, il est très probable que vous obtiendrez un fichier gzip à peine supérieur à 20 Ko.

  • tar cf folder.tar folder/ && xz --stdout folder.tar > folder.tar.xz

    Cela crée un fichier TAR comme avant, puis utilise le format xz et le compresseur LZMA / LZMA2. Je n'ai pas pu trouver d'informations sur LZMA dans cette situation, mais à partir de 7-Zip pour Windows, je sais qu'il peut prendre en charge les grandes tailles de fenêtre de dictionnaire (par exemple 64 Mio). Il est donc possible que vous utilisiez des paramètres sous-optimaux et que le codec LZMA ait pu réduire le fichier TAR à la taille d'un seul fichier PNG.

  • zip -r folder.zip folder/

    Le format ZIP ne prend pas en charge les archives "solides"; c'est-à-dire que chaque fichier est compressé indépendamment. Nous avons supposé que chaque fichier était incompressible. D'où le fait que chaque fichier est identique ne peut pas être exploité, et le fichier ZIP sera aussi gros que la concaténation directe de tous les fichiers.

Nayuki
la source
xzpar défaut s'exécute en xz -6mode, qui utilise un dictionnaire LZMA2 de 8 MiB . Je n'ai pas pu trouver immédiatement dans la page de manuel disponible sur mon système Debian quelle est la taille de fenêtre par défaut pour le compresseur.
un CVn du
Bonne réponse! Pour le deuxième cas, je faisais en fait ce qui suit: tar czf folder.tar.gz folder/ && xz --stdout folder.tar.gz > folder.tar.gz.xzsans aucun effet (ce qui est logique selon ce que vous avez expliqué). Je suppose que je me suis un peu perdu dans tous ces trucs de compression: D Lors de l'utilisation, tar cf folder.tar folder/ && xz --stdout folder.tar > folder.tar.xzje me retrouve avec un peu plus que la taille d'une image (ce qui est également logique en fonction de la taille de fenêtre de dict par défaut de 64 Mio). J'ai mis à jour ma question en conséquence. Merci!
a_guest
@a_guest D'accord, votre commentaire décrit un deuxième cas différent. Le problème est que dans tar -> gzip -> xz, le gzip DEFLATE peut compresser chaque copie des données PNG d'une manière différente, donc xz ne pourra pas détecter les redondances.
Nayuki
6

Le problème est que la plupart des schémas de compression manquent de connaissances sur les données dont vous disposez. Même si vous décompressez vos fichiers PNG en bitmaps et les compressez dans l'archive tar, vous n'obtiendrez pas de résultats (significativement) plus petits.

Dans le cas de nombreuses images similaires, un schéma de compression approprié serait un codec vidéo.

En utilisant un codage sans perte, vous devriez obtenir le résultat de compression presque parfait que vous attendez.

Si vous voulez le tester, utilisez quelque chose comme ceci:

ffmpeg -i img%03d.png -c:v libx264 -c:v libx264 -profile:v high444 -crf 0 out.mp4

https://trac.ffmpeg.org/wiki/Create%20a%20video%20slideshow%20from%20images

Jonas
la source
Bon point en utilisant un encodeur vidéo! J'essaierai cela quand j'ai mis à jour mon Ubuntu car la version 14.04 n'inclut pas ffmpeg par défaut. Je suppose que cet encodeur vidéo utilise une compression sans perte ou a au moins un commutateur pour cela? Savez-vous?
a_guest
Oui, le -crf 0 le rend sans perte (ou comme mentionné dans la documentation -qp 0 fait la même chose (-qp 0 est préféré)). trac.ffmpeg.org/wiki/Encode/H.264
Jonas
4

PNG est la combinaison de filtres + LZ77 + Huffman (la combinaison de LZ77 + Huffman est appelée Deflate) dans cet ordre:

étape 1) si le filtre est différent de None, la valeur des pixels est remplacée par la différence avec les pixels adjacents (pour plus de détails, voir http://www.libpng.org/pub/png/book/chapter09.html ) . Cela augmente la compression des images avec des dégradés (donc ... 4 5 6 7 devient ... 1 1 1 1) et cela peut aider dans les zones de la même couleur (... 3 3 3 5 5 5 5 5 devient 0 0 0 2 0 0 0 0 0). Par défaut, les filtres sont activés dans les images 24 bits et désactivés dans les images 8 bits avec une palette.

étape 2) les données sont compressées avec LZ77 qui remplace les chaînes d'octets répétées (correspond) par un tuple contenant la distance jusqu'à la correspondance et la longueur de la correspondance.

étape 3) le résultat de l'étape 2 est codé avec un code Huffman qui remplace les symboles de longueur fixe par des codes de longueur variable, plus le symbole est fréquent, plus le code est court.

Il y a plusieurs problèmes:

Un petit changement qui affecte peu de pixels entraînera des changements dans les résultats des 3 étapes de la compression png:

1) La valeur filtrée des pixels adjacents changera (en fonction du filtre utilisé). Cela amplifiera les effets de petits changements.

2) Le changement signifie que les correspondances avec cette zone seront différentes. Par exemple, si vous changez 333333 en 333533, une autre occurrence de 333333 ne correspondra plus, il sélectionnera donc une autre correspondance avec 333333 avec une distance différente ou sélectionnera la même correspondance mais avec une longueur plus courte, puis une autre correspondance pour les 3 derniers octets. En soi, cela changera beaucoup les résultats.

3) Le problème le plus important est à l'étape 3. Le code huffman utilise un nombre variable de bits, donc même un petit changement entraînera que tout ce qui suit n'est plus aligné. AFAIK La plupart des algorithmes de compression ne peuvent pas détecter les correspondances qui ne sont pas alignées en octets, ce qui empêchera (ou du moins réduira beaucoup) la compression des données déjà compressées qui suit le changement, sauf si le compresseur peut détecter des correspondances non alignées en octets.

Les autres questions sont déjà couvertes par d'autres réponses:

4) Gzip utilise le même algorithme Deflate avec un dictionnaire de 32 Ko, donc si les fichiers png sont plus grands que 32 Ko, les correspondances ne seront pas détectées même si elles sont identiques. Bzip2 est meilleur à cet égard car il utilise un bloc de 900 Ko. XZ utilise LZMA, dont l'IIRC a un dictionnaire de 4 Mo dans le niveau de compression par défaut. 5) Le format Zip n'utilise pas de compression solide, il ne compressera donc pas mieux les fichiers similaires ou identiques.

Peut-être que les compresseurs de la famille PAQ ou PPMD ​​se compresseront mieux, mais si vous devez compresser de nombreux fichiers d'images similaires, vous pouvez envisager 3 approches:

1) Stockez les images non compressées (avec PNG -0 ou dans un format sans compression) et compressez avec un compresseur avec un grand dictionnaire ou une taille de bloc. (LZMA fonctionnera bien)

2) Une autre option serait de conserver les filtres mais de supprimer la compression Deflate des PNGs. Cela peut être fait par exemple avec l' utilitaire ( AdvDef ). Ensuite, vous compressez les fichiers PNG non compressés résultants. Après la décompression, vous pouvez conserver le PNG non compressé ou les compresser à nouveau avec AdvDef (mais cela prendra du temps).

Vous devez tester les deux approches pour voir celle qui se comprime le plus.

3) La dernière option serait de convertir les images png dans une vidéo, de la compresser avec un compresseur vidéo sans perte comme x264 sans perte (en prenant particulièrement soin d'utiliser le bon format de couleur), puis d'extraire les images en images png individuelles. Cela peut être fait avec ffmpeg. Vous devez également conserver le mappage entre le numéro de trame et le nom d'origine.

Ce serait l'approche la plus complexe, mais si les pngs font tous partie d'une animation, elle peut être la plus efficace. Cependant, vous aurez besoin d'un format vidéo qui prend en charge la transparence si vous en avez besoin.

Edit: Il existe également le format MNG s'il n'est pas utilisé souvent.

ggf31416
la source
2

Lorsque vous avez des jeux de données spéciaux, vous utilisez des algorithmes spéciaux, pas des outils polyvalents.

La réponse est que les compressions sans perte que vous avez choisies ne sont pas faites pour ce que vous faites. Personne ne s'attend à ce que vous compressiez la même image deux fois, et même si vous le faites (par accident) une vérification par rapport à toutes les entrées précédentes rendrait votre algorithme O (n ^ 2) (peut-être un peu mieux, mais l'approche naïve au moins serait n ^ 2).

La plupart de vos programmes de compression que vous avez testés lors de l'exécution en O (n) mettent l'accent sur la vitesse par rapport au taux de compression optimal. Personne ne veut faire fonctionner son ordinateur pendant 5 heures juste pour épargner quelques Mo, surtout ces jours-ci. Pour les entrées plus importantes, tout ce qui dépasse O (n) devient un problème d'exécution.

Un autre problème est le bélier. Vous ne pouvez pas accéder à toutes les parties de votre entrée à un moment donné, lorsque l'entrée devient suffisamment grande. Même en faisant abstraction de cela, la plupart des gens ne veulent pas abandonner tout leur RAM ou CPU juste pour compresser quelque chose.

Si vous avez des modèles dans vos fichiers que vous souhaitez compresser, vous devrez effectuer des opérations manuelles sur eux, écrire votre propre compression ou éventuellement utiliser une compression de type "archive" (nano). Une compression pour un stockage à long terme, trop lente pour un usage quotidien.

Une autre option serait potentiellement une compression vidéo sans perte.

Si tout va bien
la source
1
Étant donné qu'il est très courant que les structures de répertoires contiennent plusieurs fichiers identiques à différents endroits, il semblerait qu'un bon utilitaire de style zip devrait fournir une option pour vérifier si un fichier ajouté à l'archive a des valeurs et des tailles de hachage compressées / non compressées. qui correspondent à ceux d'un fichier existant. Si les hachages et les deux tailles correspondent, il semblerait intéressant d'attacher un deuxième nom au bloc de données associé au premier fichier. Même si ZIP ne peut pas s'adapter à cela, cela semblerait une fonctionnalité utile dans tous les futurs formats.
supercat
1
Votre réponse implique que l'algorithme de compression de tar est bon pour compresser certains types de redondance, mais pas pour le type qui se produit dans le scénario de l'OP. Vous pourriez vouloir décrire ce genre de redondance que vous pensez qu'il est bon pour, puisque ce n'est pas du tout évident. Pour quelqu'un qui n'a peut-être jamais utilisé ce compresseur avec succès, tout ce qu'ils voient, c'est qu'ils l'ont essayé sur quelque chose qui est assez compressible en théorie, cela n'a pas fonctionné, alors à quoi bon ce compresseur est-il bon de toute façon?
Don Hatch
1
@leftaroundabout: Il n'y a aucun moyen dans les Unix que je connais d'utiliser la sémantique "copie sur écriture" avec les fichiers correspondants. Dans de nombreux cas, des copies redondantes existent pour faire face au fait que des choses qui peuvent être les mêmes aujourd'hui, peuvent ne pas être les mêmes demain, et ni liens symboliques ni liens physiques ne semblent appropriés dans de tels cas.
supercat
1
@supercat: avec bon nombre de ces fichiers, c'est une très bonne solution pour utiliser un lien symbolique vers une version «officielle» en lecture seule. Si vous souhaitez ensuite modifier votre copie, remplacez le lien symbolique par une copie physique.
leftaroundabout
1
@leftaroundabout: Une chose que j'ai parfois pensé intéressante si l'on pouvait réduire le danger de collisions de hachage artificiel à un niveau acceptable serait d'avoir un identifiant de référence universel basé sur le hachage, de sorte qu'au lieu de créer un lien symbolique vers un nom de fichier "logique" on créerait un lien basé sur le hachage. Les archives stockent alors 256 octets environ de hachage au lieu de stocker de très gros fichiers. Une variante d'une telle approche pourrait également être utilisée pour permettre la mise en cache des fichiers qui devaient être protégés contre toute altération.
supercat
2

Le format de fichier PNG utilise déjà l'algorithme de compression DEFLATE en interne. Il s'agit du même algorithme que celui utilisé par xz, gzip et zip - juste dans certaines variantes. tar.gzet et tar.xzprofiter de la similitude entre les fichiers, ce qui zipn'est pas le cas.

Donc, en fait, vous effectuez une compression DEFLATE sur des fichiers compressés DEFLATE - c'est pourquoi les fichiers conservent presque la taille d'origine.

Le bzip2programme (également un algorithme connexe) est meilleur lorsqu'il s'agit de fichiers (presque) identiques.

# for i in $(seq 4); do cp test.png test$i.png; done
# tar -cjf archive.tar.bz2 *.png
# ls -l
-rw-r--r-- 1 abcde users  43813 15. Jul 08:45 test.png
-rw-r--r-- 1 abcde users  43813 15. Jul 08:45 test1.png
-rw-r--r-- 1 abcde users  43813 15. Jul 08:46 test2.png
-rw-r--r-- 1 abcde users  43813 15. Jul 08:46 test3.png
-rw-r--r-- 1 abcde users  43813 15. Jul 08:46 test4.png
-rw-r--r-- 1 abcde users  68115 15. Jul 08:47 archive.tar.bz2
rexkogitans
la source
PNG - veuillez garder à l'esprit qu'il existe des filtres utilisés, un dégonflage non standard (lequel est standard de toute façon?) Et vous avez raison de dire que l'exécution du même algorithme deux fois ne donne rien (ou du moins cela ne devrait pas être bénéfique), mais l'exécution de la échec du même algorithme avec des paramètres différents. Il existe également des différences entre deflate32, deflate64, LZW, LZMA, vous ne pouvez pas simplement dire que tous utilisent le même dégonflage.
Evil
C'est pourquoi j'ai dit "dans certaines variantes". Bien sûr, DEFLATE fait référence à une sorte d'algorithme plutôt qu'à une certaine implémentation.
rexkogitans
3
Cela manque le point tel que je le comprends. Oui, un seul fichier PNG est déjà compressé, donc je ne m'attendrais pas à ce qu'une compression supplémentaire de quelque sorte ait beaucoup d'effet. Mais on peut raisonnablement s'attendre à ce qu'une concaténation de plusieurs fichiers PNG identiques (ce qui est essentiellement le cas ici) se comprime à pas plus que la taille de l'un d'eux.
Don Hatch
De toute évidence, ces algorithmes de compression manquent ce point. bzip2attrape: tar -cjf archive.tar.bz2 *.png. Mis à jour dans ma réponse.
rexkogitans