Convertissez des milliers de .pngs en .gif animé, `convert` utilise trop de mémoire


29

Beaucoup de questions demandant comment créer un gif animé à partir d'un ensemble d'images png suggèrent d'utiliser une variante de la convertcommande ImageMagick :

convert -delay 2 -loop 0 *.png animated.gif

Cependant, j'ai quelques milliers d'images et convertutilise donc toute ma mémoire, échange, puis plante. Quels logiciels alternatifs existent, qui sont plus sensibles à la mémoire? Je pourrais utiliser un autre format ouvert s'il .gifn'est pas pris en charge, et je préfère un outil CLI.


1
Que diriez-vous de diviser les fichiers * .png en morceaux gérables? Supposons que tous les noms de fichiers commencent par un chiffre, puis convert -delay 2 -loop 0 0*.png animated.gifne convertiront que les fichiers commençant par un «0». Etc.
Jos

2
Donc, chaque .png est de l'ordre de 1 Mb? Dans ce cas, tout ce à quoi je peux penser est de convertir d'abord les fichiers .png en une résolution ou une profondeur de couleur inférieure, pour les réduire.
Jos

10
Vous dites que vous pourriez utiliser un autre format ouvert. Il me semble que gif n'est pas exactement le meilleur format pour des milliers d'images. Avez-vous plutôt pensé à encoder une vidéo avec Ogg Theora?
rekado

1
Jetez peut-être un œil au gifsicle , si vous voulez vraiment utiliser le GIF? (Bien que, comme d'autres l'ont dit, ce ne soit pas la raison pour laquelle le GIF a été créé; OGG serait un meilleur choix.)
wchargin

1
Ré. "où va toute la mémoire": 65 Ko est la taille de fichier d'une image compressée. Lorsqu'elle n'est pas compressée, l'image prend environ 4 x largeur x hauteur octets, donc une image 1024x768 prendrait ~ 3 Mo de RAM. Multipliez cela par "quelques milliers" et vous verrez où va la mémoire ...
Sergey

Réponses:


33

On dirait que vous essayez de faire une vidéo. Si tel est le cas, j'utiliserais un format vidéo approprié.

Dans ce cas, j'utiliserais ffmpeg pour convertir les fichiers PNG individuels en vidéo H.264. Étant donné que ffmpeg est conçu pour fonctionner avec des vidéos pouvant durer des heures, il ne devrait pas avoir de problème avec vos milliers d'images. En utilisant H.264 au lieu de GIF animés entraînera une grande amélioration de la qualité de l' image.

Quelque chose comme ça devrait fonctionner pour vous:

 ffmpeg -framerate 1/2 -i img%04d.png -c:v libx264 -r 30 out.mp4
  • -framerate 1/2: Cela définit le framerate à un demi-FPS, ou 2 secondes par image.
  • -i img%04d.png: Cela indique ffmpeg pour lire les fichiers img0000.pngbien img9999.png.
  • -c:v libx264: Utilisez le codec vidéo libx264.
    • Vous pouvez spécifier des paramètres de compression vidéo ici, si vous le souhaitez:
    • -crf <number>: Réglage de qualité. 0 à 51. 23 est la valeur par défaut. 0 est un véritable codage sans perte, qui sera une bande passante assez élevée. 18 est presque sans perte visuelle.
  • -r 30: Définissez la fréquence d'images de sortie sur 30 FPS. Chacune des images d'entrée sera dupliquée pour faire de la sortie ce que vous spécifiez ici. Vous pouvez laisser ce paramètre désactivé et le fichier de sortie sera à la fréquence d'images en entrée, mais le film résultant ne s'affichait pas correctement lorsque je l'ai essayé tout à l'heure.
  • out.mp4: Nom du fichier de sortie.

Les références:


1
Belle extension de la réponse de Frantique de la veille.
Elder Geek

Voici un benchmark ffmpeg vs ImageMagick simple avec des données de test concrètes: askubuntu.com/questions/648244/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

11

Personnellement, je le lancerais simplement sur un nombre limité de fichiers au lieu de tous en même temps. Par exemple, quelque chose comme ceci:

#!/usr/bin/env bash

## Collect all png files in the files array
files=( *png )
## How many should be done at once
batch=50

## Read the array in batches of $batch
for (( i=0; $i<${#files[@]}; i+=$batch ))
do
    ## Convert this batch
    convert -delay 2 -loop 0 "${files[@]:$i:$batch}" animated.$i.gif
done

## Now, merge them into a single file
convert  animated.*.gif all.gif

8

Utilisez -limit memory 1GiBpour limiter la quantité de mémoire convertutilisée.

Des milliers d'images créeraient un énorme GIF que la plupart des ordinateurs auront du mal à afficher. Je conserve mes GIF animés en dessous de 200 images lorsque cela est possible. Le moins c'est le mieux. Si vous numérotez vos images, cette commande supprimera les images impaires rm *[13579].png.

Voici donc mon flux de travail typique pour créer un GIF animé à partir d'une scène de film:

avconv -ss 00:26:00 -i someMovie.mpg %5d.png
rm  *[13579].png
convert -limit memory 1GiB -loop 0 -layers optimize -resize 400 *.png output.gif

1
Merci, cette solution fonctionne bien. Il peut également être nécessaire d'augmenter les limites de mémoire autorisées dans /etc/ImageMagick-6/policy.xml voir github.com/ImageMagick/ImageMagick/issues/… pour plus d'informations
Louis Gagnon

4

Je pourrais utiliser un autre format ouvert s'il .gifn'est pas pris en charge

APNG vous est peut-être utile. Il est pris en charge par certains navigateurs , y compris Firefox, mais exclut actuellement Chrome et IE. Comme il ne s'agit que d'une extension PNG, il est très simple de convertir des PNG en APNG. L' outil d' apngasme peut le faire. Mais le format est si simple que j'ai récemment écrit moi-même un assembleur APNG pour Sage. L'adaptation de ce code serait une alternative.


Je voudrais également souligner que l'APNG n'est pas standard et bien qu'il existe depuis 7 ans, il est toujours très obscur.
Pharap

Pour une démonstration scientifique, où vous pourriez être en mesure de choisir le navigateur utilisé pour cela, cela pourrait encore être une solution simple et robuste.
MvG

Cela dépend de qui doit voir la démonstration. Il ne serait pas très bon de remettre des copies aux téléspectateurs, puis les deux tiers doivent s'éteindre et télécharger Firefox juste pour le voir. Pas le genre d'impression que j'aimerais faire si je faisais une importante démonstration scientifique. S'il est uniquement destiné à être considéré comme faisant partie de la démonstration, il est juste, mais il peut ne pas convenir à d'autres situations.
Pharap

3

Si vous avez des milliers de png-s, le format anigif est bizarre. Je le ferais de cette façon, en utilisant avconv:

 avconv -i "%d.png" -r 25 -c:v libx264 -crf 20 -pix_fmt yuv420p animated.mov

Cette approche a l'avantage supplémentaire que vous pourriez plus tard muxer en voix-off ou en musique, ce qui est impossible avec le Graphics Interchange Format.
Elder Geek

2

gifsicle est un utilitaire en ligne de commande pour gérer les animations GIF. Si vous souhaitez échanger de la mémoire contre de la vitesse, vous pouvez utiliser son commutateur --conserve-memory.


Permettez-moi de le dire ainsi: gifsicle a déjà une empreinte plus petite que ImageMagick - si vous trouvez qu'il utilise toujours trop de mémoire pour la tâche à accomplir, alors vous pouvez utiliser --conserve-memory
codehead

Ohh, je pense que j'ai mal lu ce que vous disiez, que le commutateur utiliserait plus de mémoire, ce qui n'a pas beaucoup de sens. ça ne fait rien.
curiousdannii

2

En plus d'autres réponses: puisque vous voulez produire un fichier GIF, je suppose que vous voulez afficher l'image sur une page Web. Si c'est le cas, je ne prendrais pas la peine de convertir vos fichiers PNG du tout. Il suffit de google pour "diaporama javascript" et d'utiliser l'un des millions de scripts gratuits. Ou écrivez le vôtre, c'est vraiment trivial.

Les avantages de procéder de cette façon sont les suivants:

  • une seule image est chargée dans le navigateur à tout moment, le diaporama démarre rapidement et ne consomme pas beaucoup de RAM sur la machine de l'utilisateur.

  • la solution évolue vers des millions d'images. Ou des milliards, si vous êtes assez patient pour les regarder tous :)

  • Vous pouvez ajouter des contrôles à votre page pour mettre en pause, rembobiner, modifier le délai ou accéder à un cadre particulier.


Merci Sergey. En fait, ce n'est pas pour l'affichage sur une page Web. +1 pour l'idée, cependant.
dotancohen
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.