Konversi ribuan .pngs ke animasi .gif, `convert` menggunakan terlalu banyak memori

29

Banyak pertanyaan yang menanyakan cara membuat animasi gif dari serangkaian gambar png menyarankan untuk menggunakan varian convertperintah ImageMagick :

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

Namun, saya memiliki beberapa ribu gambar dan karenanya convertmenggunakan semua memori saya, swap, dan kemudian crash. Perangkat lunak alternatif apa yang ada, yang lebih sadar akan memori? Saya bisa menggunakan format terbuka lain jika .giftidak didukung, dan saya lebih suka alat CLI.

dotancohen
sumber
1
Bagaimana dengan membagi file * .png menjadi potongan yang bisa dikelola? Katakanlah semua nama file mulai dengan angka, kemudian convert -delay 2 -loop 0 0*.png animated.gifhanya akan mengonversi file yang dimulai dengan '0'. Dan seterusnya.
Jos
2
Jadi, masing-masing .png berada di urutan 1 Mb? Dalam hal itu, yang bisa saya pikirkan adalah pertama-tama mengkonversi file .png ke resolusi yang lebih rendah atau kedalaman warna, untuk membuatnya lebih kecil.
Jos
10
Anda mengatakan bahwa Anda dapat menggunakan format terbuka lainnya. Sepertinya saya bahwa gif bukan format terbaik untuk ribuan frame. Sudahkah Anda mempertimbangkan untuk meng-encode video dengan Ogg Theora?
rekado
1
Mungkin lihat gifsicle , apakah Anda benar-benar ingin menggunakan GIF? (Meskipun, seperti yang orang lain katakan, ini bukan tujuan GIF; OGG akan menjadi pilihan yang lebih baik.)
wchargin
1
Kembali. "di mana semua memori pergi": 65 Kb adalah ukuran file dari gambar yang dikompresi. Saat tidak dikompresi, gambar membutuhkan kira-kira 4 x lebar x tinggi byte, sehingga gambar 1024x768 akan mengambil ~ 3Mb RAM. Lipat gandakan dengan "beberapa ribu" dan Anda akan melihat ke mana ingatannya ...
Sergey

Jawaban:

33

Sepertinya Anda mencoba membuat video. Jika itu masalahnya, maka saya akan menggunakan format video yang tepat.

Dalam hal ini, saya akan menggunakan ffmpeg untuk mengonversi masing-masing file PNG menjadi video H.264. Karena ffmpeg dibuat untuk bekerja dengan video yang bisa memakan waktu berjam-jam, ffmpeg seharusnya tidak memiliki masalah dengan ribuan gambar Anda. Menggunakan H.264 sebagai gif animasi tidak akan menghasilkan peningkatan besar dalam kualitas gambar.

Sesuatu seperti ini seharusnya bekerja untuk Anda:

 ffmpeg -framerate 1/2 -i img%04d.png -c:v libx264 -r 30 out.mp4
  • -framerate 1/2: Ini mengatur framerate menjadi satu-setengah FPS, atau 2 detik per frame.
  • -i img%04d.png: Ini memberitahu ffmpeg untuk membaca file img0000.pngsekalipun img9999.png.
  • -c:v libx264: Gunakan video codec libx264.
    • Anda dapat menentukan parameter kompresi video di sini, jika Anda suka:
    • -crf <number>: Pengaturan kualitas. 0 hingga 51. 23 adalah standarnya. 0 adalah benar pengkodean lossless, yang akan menjadi bandwidth yang cukup tinggi. 18 hampir tanpa kehilangan secara visual.
  • -r 30: Atur framerate output ke 30 FPS. Setiap gambar input akan diduplikasi untuk menghasilkan apa yang Anda tentukan di sini. Anda dapat membiarkan parameter ini mati, dan file output akan berada di framerate input, tetapi film yang dihasilkan tidak ditampilkan dengan benar ketika saya mencobanya sekarang.
  • out.mp4: Nama file keluaran.

Referensi:

David Yaw
sumber
1
Ekspansi Frantique yang bagus dari hari sebelumnya.
Penatua Geek
Berikut ini adalah patokan ffmpeg vs ImageMagick sederhana dengan data uji konkret: askubuntu.com/questions/648244/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
11

Secara pribadi, saya hanya akan meluncurkannya dalam jumlah file terbatas, bukan sekaligus. Misalnya, sesuatu seperti ini:

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

Gunakan -limit memory 1GiBuntuk membatasi jumlah convertpenggunaan memori .

1000-an gambar akan membuat GIF besar yang sebagian besar komputer akan berjuang untuk ditampilkan. Saya menyimpan animasi GIF saya di bawah 200 gambar bila memungkinkan. Semakin sedikit semakin baik. Jika Anda memberi nomor pada gambar Anda, perintah ini akan menghapus gambar bernomor ganjil rm *[13579].png.

Jadi di sini adalah alur kerja khas saya untuk membuat animasi GIF dari adegan 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
PLA
sumber
1
Terima kasih, solusi itu bekerja dengan baik. Mungkin juga diperlukan untuk meningkatkan batas memori yang diperbolehkan di /etc/ImageMagick-6/policy.xml lihat github.com/ImageMagick/ImageMagick/issues/… untuk info lebih lanjut
Louis Gagnon
4

Saya dapat menggunakan format terbuka lain jika .giftidak didukung

Mungkin APNG berguna bagi Anda. Ini didukung oleh beberapa browser , termasuk Firefox tetapi saat ini tidak termasuk Chrome dan IE. Karena ini hanya ekstensi PNG, sangat mudah untuk mengonversi PNG ke APNG. Alat apngasme dapat melakukannya. Tetapi formatnya sangat sederhana sehingga saya baru-baru ini menulis assembler APNG sendiri untuk Sage. Mengadaptasi kode itu akan menjadi alternatif.

MvG
sumber
Saya juga ingin menunjukkan bahwa APNG adalah non-standar dan meskipun sudah ada selama 7 tahun masih sangat tidak jelas.
Pharap
Untuk demonstrasi ilmiah, di mana Anda mungkin dapat memilih browser yang digunakan untuk itu, ini mungkin masih merupakan solusi sederhana dan kuat
MvG
Tergantung siapa yang harus melihat demonstrasi. Ini tidak akan sangat baik untuk membagikan salinan kepada pemirsa dan kemudian dua pertiga harus pergi dan mengunduh Firefox hanya untuk melihatnya. Bukan jenis kesan yang ingin saya buat jika saya membuat demonstrasi ilmiah yang penting. Jika itu hanya dimaksudkan untuk dilihat sebagai bagian dari demonstrasi maka cukup adil, tetapi mungkin tidak cocok untuk situasi lain.
Pharap
3

Jika Anda memiliki ribuan png-s, format anigif aneh. Saya akan melakukannya dengan cara ini, menggunakan avconv:

 avconv -i "%d.png" -r 25 -c:v libx264 -crf 20 -pix_fmt yuv420p animated.mov
Frantique
sumber
Pendekatan ini memiliki manfaat tambahan yang nantinya bisa Anda sesuaikan dengan voice-over atau audio musik yang tidak mungkin dilakukan dengan Format Interchange Grafik.
Penatua Geek
2

gifsicle adalah utilitas baris perintah untuk menangani animasi GIF. Jika Anda ingin menukar memori dengan kecepatan, Anda dapat menggunakan sakelar --conserve-memory.

kepala kode
sumber
Biarkan saya begini: gifsicle sudah memiliki jejak yang lebih kecil daripada ImageMagick - jika Anda menemukan bahwa itu masih menggunakan terlalu banyak memori untuk tugas yang sedang dikerjakan, maka Anda dapat menggunakan --conserve-memory
codehead
Ohh, saya pikir saya salah membaca apa yang Anda katakan, bahwa saklar akan menggunakan lebih banyak memori, yang tidak masuk akal. sudahlah.
curiousdannii
2

Selain jawaban lain: karena Anda ingin menghasilkan file GIF, saya berasumsi Anda ingin menampilkan gambar di halaman web. Jika demikian, saya tidak akan repot mengubah PNG Anda sama sekali. Cukup google untuk "slideshow javascript" dan gunakan salah satu dari jutaan skrip gratis. Atau tulis sendiri, ini benar-benar sepele.

Manfaat melakukannya dengan cara ini adalah:

  • hanya satu gambar yang dimuat di browser kapan saja, pertunjukan slide dimulai dengan cepat dan tidak mengkonsumsi banyak RAM pada mesin pengguna.

  • solusi ini menskala jutaan gambar. Atau miliaran, jika Anda cukup sabar untuk menonton semuanya :)

  • Anda dapat menambahkan kontrol ke halaman Anda untuk menjeda, mundur, mengubah penundaan atau pergi ke bingkai tertentu.

Sergey
sumber
Terima kasih, Sergey. Sebenarnya ini bukan untuk ditampilkan pada halaman web. +1 untuk gagasan itu.
dotancohen