Konvertieren Sie Tausende von .pngs in animiertes .gif, `convert` verbraucht zu viel Speicher

29

Bei vielen Fragen zur Erstellung eines animierten Gifs aus einer Reihe von PNG-Bildern wird die Verwendung einer Variante des ImageMagick- convertBefehls empfohlen :

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

Ich habe jedoch einige tausend Bilder und convertverbrauche so meinen gesamten Speicher, tausche und stürze dann ab. Welche alternative Software gibt es, die speicherbewusster ist? Ich könnte ein anderes offenes Format verwenden, wenn .gifes nicht unterstützt wird, und ich bevorzuge ein CLI-Tool.

dotancohen
quelle
1
Wie wäre es, wenn Sie die * .png-Dateien in überschaubare Teile aufteilen würden? Angenommen, alle Dateinamen beginnen mit einer Ziffer und convert -delay 2 -loop 0 0*.png animated.gifkonvertieren dann nur die Dateien, die mit einer '0' beginnen. Und so weiter.
Jos
2
Also ist jede .png in der Größenordnung von 1 MB? In diesem Fall muss ich nur die PNG-Dateien in eine niedrigere Auflösung oder Farbtiefe konvertieren, um sie zu verkleinern.
Jos
10
Sie sagen, Sie könnten ein anderes offenes Format verwenden. Es scheint mir, dass GIF nicht gerade das beste Format für Tausende von Frames ist. Hast du überlegt, stattdessen ein Video mit Ogg Theora zu kodieren?
Rekado
1
Vielleicht werfen Sie einen Blick auf Gifsicle , wenn Sie wirklich GIF verwenden möchten? (Obwohl, wie andere gesagt haben, dies nicht das ist, wofür GIF gemacht wurde; OGG wäre eine bessere Wahl.)
wchargin
1
Re. "wohin der gesamte Speicher geht": 65 Kb ist die Dateigröße eines komprimierten Bildes. Im unkomprimierten Zustand benötigt das Image ungefähr 4 x Breite x Höhe Bytes, sodass ein 1024x768-Image ca. 3 MB RAM benötigt. Multiplizieren Sie das mit "ein paar Tausend" und Sie werden sehen, wohin die Erinnerung geht ...
Sergey

Antworten:

33

Es hört sich so an, als würden Sie versuchen, ein Video zu machen. In diesem Fall würde ich ein geeignetes Videoformat verwenden.

In diesem Fall würde ich ffmpeg verwenden , um die einzelnen PNG-Dateien in ein H.264-Video zu konvertieren. Da ffmpeg mit Videos arbeitet, die Stunden lang sein können, sollte es kein Problem mit Ihren Tausenden von Bildern geben. Die Verwendung von H.264 anstelle von animiertem GIF führt zu einer erheblichen Verbesserung der Bildqualität.

So etwas sollte für Sie funktionieren:

 ffmpeg -framerate 1/2 -i img%04d.png -c:v libx264 -r 30 out.mp4
  • -framerate 1/2: Hiermit stellen Sie die Bildrate auf eine halbe FPS oder 2 Sekunden pro Bild ein.
  • -i img%04d.png: Dies sagt ffmpeg die Dateien zu lesen , img0000.pngobwohl img9999.png.
  • -c:v libx264: Verwenden Sie den Videocodec libx264.
    • Sie können hier Videokomprimierungsparameter angeben, wenn Sie möchten:
    • -crf <number>: Qualitätseinstellung. 0 bis 51. 23 ist die Standardeinstellung. 0 ist eine verlustfreie Codierung, die eine recht hohe Bandbreite bietet. 18 ist optisch nahezu verlustfrei.
  • -r 30: Stellen Sie die Ausgangsbildrate auf 30 FPS ein. Jedes der eingegebenen Bilder wird dupliziert, um die Ausgabe zu dem zu machen, was Sie hier angeben. Sie können diesen Parameter auslassen, und die Ausgabedatei wird in der Eingangsframerate angezeigt, aber der resultierende Film wurde nicht richtig angezeigt, als ich ihn gerade ausprobierte.
  • out.mp4: Name der Ausgabedatei.

Verweise:

David Yaw
quelle
1
Schöne Erweiterung von Frantique Antwort vom Vortag.
Elder Geek
Hier ist ein einfacher ffmpeg vs ImageMagick Benchmark mit konkreten Testdaten: askubuntu.com/questions/648244/…
Ciro Santilli am
11

Persönlich würde ich es nur in einer begrenzten Anzahl von Dateien anstatt auf einmal starten. Zum Beispiel so etwas:

#!/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
terdon
quelle
8

Verwenden Sie -limit memory 1GiBdiese Option , um den Speicherbedarf zu begrenzen convert.

Tausende von Bildern würden ein riesiges GIF erzeugen, das auf den meisten Computern nur schwer angezeigt werden kann. Ich halte meine animierten GIFs nach Möglichkeit unter 200 Bildern. Je weniger desto besser. Wenn Sie Ihre Bilder nummerieren, werden mit diesem Befehl die ungeraden Bilder gelöscht rm *[13579].png.

Hier ist mein typischer Workflow zum Erstellen eines animierten GIF aus einer Filmszene:

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
PLA
quelle
1
Danke, diese Lösung funktioniert gut. Möglicherweise müssen Sie auch die zulässigen Speichergrenzen in /etc/ImageMagick-6/policy.xml erhöhen. Weitere Informationen finden Sie unter github.com/ImageMagick/ImageMagick/issues/…
Louis Gagnon,
4

Ich könnte ein anderes offenes Format verwenden, wenn .gifes nicht unterstützt wird

Vielleicht hilft Ihnen APNG . Es wird von einigen Browsern unterstützt , einschließlich Firefox, derzeit jedoch ohne Chrome und IE. Da es sich nur um eine PNG-Erweiterung handelt, ist es sehr einfach, PNGs in APNG zu konvertieren. Das Apngasmus- Tool kann das. Aber das Format ist so einfach, dass ich kürzlich selbst einen APNG-Assembler für Sage geschrieben habe. Eine Anpassung dieses Codes wäre eine Alternative.

MvG
quelle
Ich möchte auch darauf hinweisen, dass APNG nicht dem Standard entspricht und obwohl es das seit 7 Jahren gibt, immer noch sehr dunkel ist.
Pharap
Für eine wissenschaftliche Demonstration, bei der Sie möglicherweise den dafür verwendeten Browser auswählen können, ist dies möglicherweise eine einfache und robuste Lösung.
MvG
Es kommt darauf an, wer die Demonstration sehen muss. Es wäre nicht sehr gut, Kopien an die Zuschauer zu verteilen, und dann müssen zwei Drittel Firefox herunterladen, um es anzusehen. Nicht die Art von Eindruck, die ich machen möchte, wenn ich eine wichtige wissenschaftliche Demonstration mache. Wenn es nur als Teil der Demonstration angesehen werden soll, ist es fair genug, aber für andere Situationen möglicherweise nicht geeignet.
Pharap
3

Wenn Sie Tausende von png-s haben, ist das Anigif-Format seltsam. Ich würde es auf diese Weise tun, mit avconv:

 avconv -i "%d.png" -r 25 -c:v libx264 -crf 20 -pix_fmt yuv420p animated.mov
Frantique
quelle
Dieser Ansatz hat den zusätzlichen Vorteil, dass Sie später Voice-Over- oder Musik-Audio muxen können, was mit dem Graphics Interchange Format nicht möglich ist.
Elder Geek
2

gifsicle ist ein Befehlszeilenprogramm für die Verarbeitung von GIF-Animationen. Wenn Sie Speicher gegen Geschwindigkeit eintauschen möchten, können Sie den Schalter --conserve-memory verwenden.

Codehead
quelle
Lassen Sie es mich so sagen: gifsicle hat bereits eine kleinere Grundfläche als ImageMagick - wenn Sie feststellen , dass es nach wie vor für die Aufgabe in der Hand zu viel Speicher verwendet, dann können Sie --conserve-Speicher verwenden
codehead
Ohh, ich glaube, ich habe falsch verstanden, was Sie gesagt haben, dass der Schalter mehr Speicher verbrauchen würde, was nicht viel Sinn macht. keine Ursache.
curiousdannii
2

Neben anderen Antworten: Da Sie eine GIF-Datei erstellen möchten, gehe ich davon aus, dass Sie das Bild auf einer Webseite anzeigen möchten. Wenn ja, würde ich mich überhaupt nicht darum kümmern, deine PNGs zu konvertieren. Suchen Sie einfach bei Google nach "Javascript Diashow" und verwenden Sie eines der Millionen kostenlosen Skripte. Oder schreiben Sie Ihre eigenen, das ist wirklich trivial.

Die Vorteile dieser Vorgehensweise sind:

  • Es wird immer nur ein Bild in den Browser geladen, die Diashow startet schnell und beansprucht nicht viel RAM auf dem Computer des Benutzers.

  • Die Lösung lässt sich auf Millionen von Bildern skalieren. Oder Milliarden, wenn Sie geduldig genug sind, um sie alle zu sehen :)

  • Sie können Ihrer Seite Steuerelemente hinzufügen, um anzuhalten, zurückzuspulen, die Verzögerung zu ändern oder zu einem bestimmten Frame zu wechseln.

Sergey
quelle
Vielen Dank, Sergey. Tatsächlich ist dies nicht für die Anzeige auf einer Webseite vorgesehen. +1 für die Idee.
Dotancohen