Converti migliaia di .png in .gif animato, `convert` usa troppa memoria


29

Molte delle domande che chiedono come creare una gif animata da una serie di immagini png suggeriscono di usare una variante del convertcomando di ImageMagick :

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

Tuttavia, ho alcune migliaia di immagini e quindi convertesaurisco tutta la mia memoria, lo scambio e poi si blocca. Quale software alternativo esiste, che è più sensibile alla memoria? Potrei usare un altro formato aperto se .gifnon è supportato e preferisco uno strumento CLI.


1
Che ne dici di dividere i file * .png in blocchi gestibili? Supponiamo che tutti i nomi di file inizino con una cifra, quindi convert -delay 2 -loop 0 0*.png animated.gifconvertiranno solo i file che iniziano con uno "0". E così via.
Jos

2
Quindi ogni .png è nell'ordine di 1 Mb? In quel caso, tutto ciò che mi viene in mente è di convertire prima i file .png in una risoluzione o profondità di colore inferiore, per renderli più piccoli.
Jos

10
Dici che potresti usare un altro formato aperto. Mi sembra che GIF non sia esattamente il miglior formato per migliaia di frame. Hai mai considerato la codifica di un video con Ogg Theora?
rekado,

1
Forse dai un'occhiata a gifsicle , se vuoi davvero usare GIF? (Anche se, come altri hanno già detto, non è per questo che è stata creata la GIF; OGG sarebbe una scelta migliore.)
wchargin

1
Ri. "dove sta andando tutta la memoria": 65 Kb è la dimensione del file di un'immagine compressa. Se non compresso, l'immagine richiede circa 4 x larghezza x altezza byte, quindi un'immagine 1024x768 richiederebbe ~ 3 MB di RAM. Moltiplicalo per "qualche migliaio" e vedrai dove sta andando la memoria ...
Sergey

Risposte:


33

Sembra che tu stia provando a fare un video. In tal caso, utilizzerei un formato video adeguato.

In questo caso, userei ffmpeg per convertire i singoli file PNG in un video H.264. Poiché ffmpeg è progettato per funzionare con video che possono durare ore, non dovrebbe avere problemi con le tue migliaia di immagini. L'uso di H.264 invece di GIF animate comporterà un notevole miglioramento della qualità dell'immagine.

Qualcosa del genere dovrebbe funzionare per te:

 ffmpeg -framerate 1/2 -i img%04d.png -c:v libx264 -r 30 out.mp4
  • -framerate 1/2: Imposta il framerate su metà FPS o 2 secondi per fotogramma.
  • -i img%04d.png: Questo dice a ffmpeg di leggere i file img0000.pngperò img9999.png.
  • -c:v libx264: Utilizza il codec video libx264.
    • Puoi specificare qui i parametri di compressione video, se ti piace:
    • -crf <number>: Impostazione della qualità. Da 0 a 51. 23 è l'impostazione predefinita. 0 è una vera codifica lossless, che sarà una larghezza di banda piuttosto elevata. 18 è quasi visivamente senza perdita.
  • -r 30: Imposta il framerate di uscita su 30 FPS. Ognuna delle immagini di input verrà duplicata per rendere l'output quello specificato qui. Puoi lasciare questo parametro disattivato e il file di output sarà al framerate di input, ma il film risultante non è stato visualizzato correttamente quando l'ho provato proprio ora.
  • out.mp4: Nome file di output.

Riferimenti:


1
Bella espansione della risposta di Frantique del giorno prima.
Elder Geek,

Ecco un semplice benchmark ffmpeg vs ImageMagick con dati di test concreti: askubuntu.com/questions/648244/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

11

Personalmente, vorrei semplicemente lanciarlo su un numero limitato di file anziché su tutti contemporaneamente. Ad esempio, qualcosa del genere:

#!/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

Utilizzare -limit memory 1GiBper limitare la quantità di memoria convertutilizzata.

Migliaia di immagini creerebbero un'enorme GIF che la maggior parte dei computer avrà difficoltà a visualizzare. Tengo le mie GIF animate al di sotto di 200 immagini quando possibile. Meno è, meglio è. Se numeri le tue immagini, questo comando eliminerà le immagini dispari rm *[13579].png.

Ecco quindi il mio flusso di lavoro tipico per la creazione di una GIF animata da una scena cinematografica:

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
Grazie, quella soluzione funziona bene. Potrebbe anche essere necessario aumentare i limiti di memoria consentiti in /etc/ImageMagick-6/policy.xml vedi github.com/ImageMagick/ImageMagick/issues/… per maggiori informazioni
Louis Gagnon

4

Potrei usare un altro formato aperto se .gifnon è supportato

Forse APNG ti è utile. È supportato da alcuni browser , incluso Firefox, ma al momento esclude Chrome e IE. Dal momento che è solo un'estensione PNG, è molto semplice convertire i PNG in APNG. Lo strumento apngasm può farlo. Ma il formato è così semplice che di recente ho scritto un assemblatore APNG per Sage. Adattare quel codice sarebbe un'alternativa.


Vorrei anche sottolineare che APNG non è standard e nonostante sia in circolazione da 7 anni è ancora molto oscuro.
Pharap,

Per una dimostrazione scientifica, in cui potresti essere in grado di scegliere il browser utilizzato per questo, questa potrebbe essere comunque una soluzione semplice e affidabile.
MvG,

Dipende da chi deve vedere la dimostrazione. Non sarebbe molto bello distribuire copie agli spettatori e quindi i due terzi devono spegnersi e scaricare Firefox solo per vederlo. Non il tipo di impressione che vorrei fare se stessi facendo un'importante dimostrazione scientifica. Se è inteso solo per essere visto come parte della dimostrazione, allora è abbastanza giusto, ma potrebbe non essere adatto ad altre situazioni.
Pharap,

3

Se hai migliaia di png-s, il formato anigif è strano. Lo farei in questo modo, usando avconv:

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

Questo approccio ha l'ulteriore vantaggio di poter in seguito fondere in voice-over o audio musicale, cosa impossibile con Graphics Interchange Format.
Elder Geek,

2

gifsicle è un'utilità da riga di comando per gestire animazioni GIF. Se sei disposto a scambiare memoria per la velocità, puoi usare il suo interruttore --conserve-memory.


Mettiamola in questo modo: Gifsicle ha già un ingombro più piccolo di ImageMagick - se si scopre che si usa ancora troppa memoria per il compito a portata di mano, quindi è possibile utilizzare --conserve-memoria
codehead

Ohh, penso di aver letto male quello che stavi dicendo, che l'interruttore avrebbe usato più memoria, il che non ha molto senso. non importa.
curiousdannii,

2

Oltre ad altre risposte: dal momento che vuoi produrre un file GIF, suppongo che tu voglia visualizzare l'immagine su una pagina web. In tal caso, non mi preoccuperei affatto di convertire i tuoi PNG. Basta google per "slideshow javascript" e utilizzare uno dei milioni di script gratuiti. Oppure scrivi il tuo, questo è davvero banale.

I vantaggi di farlo in questo modo sono:

  • nel browser viene caricata una sola immagine alla volta, la presentazione si avvia rapidamente e non consuma molta RAM sul computer dell'utente.

  • la soluzione si ridimensiona a milioni di immagini. O miliardi, se sei abbastanza paziente da guardarli tutti :)

  • È possibile aggiungere controlli alla pagina per mettere in pausa, riavvolgere, modificare il ritardo o passare a un determinato fotogramma.


Grazie Sergey. In realtà questo non è per la visualizzazione su una pagina web. +1 per l'idea, però.
dotancohen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.