Konwertuj tysiące plików .png na animowane .gif, „konwersja” zużywa zbyt dużo pamięci

29

Wiele pytań dotyczących tworzenia animowanego gifa z zestawu obrazów png sugeruje użycie wariantu convertpolecenia ImageMagick :

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

Mam jednak kilka tysięcy zdjęć i dlatego convertzużywa całą moją pamięć, zamienia, a następnie ulega awarii. Jakie istnieje alternatywne oprogramowanie, które jest bardziej świadome pamięci? Mógłbym użyć innego otwartego formatu, jeśli .gifnie jest obsługiwany, i wolę narzędzie CLI.

dotancohen
źródło
1
Co powiesz na podzielenie plików * .png na porcje do zarządzania? Powiedzmy, że wszystkie nazwy plików zaczynają się od cyfry, a następnie convert -delay 2 -loop 0 0*.png animated.gifkonwertują tylko pliki, które zaczynają się od „0”. I tak dalej.
Jos
2
Więc każdy plik .png jest rzędu 1 Mb? W takim przypadku mogę jedynie przekonwertować pliki .png na niższą rozdzielczość lub głębię kolorów, aby je zmniejszyć.
Jos
10
Mówisz, że możesz użyć innego otwartego formatu. Wydaje mi się, że gif nie jest najlepszym formatem dla tysięcy ramek. Czy zamiast tego zastanawiałeś się nad kodowaniem wideo za pomocą Ogg Theora?
rekado
1
Może rzucisz okiem na gifsicle , jeśli naprawdę chcesz użyć GIF? (Chociaż, jak powiedzieli inni, nie po to GIF został stworzony; OGG byłby lepszym wyborem.)
wchargin
1
Re. „dokąd zmierza cała pamięć”: 65 Kb to rozmiar skompresowanego obrazu. Po nieskompresowaniu obraz zajmuje około 4 x szerokość x wysokość bajtów, więc obraz 1024 x 768 zajmie około 3 MB pamięci RAM. Pomnóż to przez „kilka tysięcy”, a zobaczysz, dokąd zmierza pamięć…
Sergey

Odpowiedzi:

33

Wygląda na to, że próbujesz nagrać film. W takim przypadku użyłbym odpowiedniego formatu wideo.

W takim przypadku użyłbym ffmpeg do konwersji pojedynczych plików PNG na wideo H.264. Ponieważ ffmpeg jest przystosowany do pracy z filmami, które mogą trwać wiele godzin, nie powinien mieć problemu z tysiącami twoich zdjęć. Użycie H.264 zamiast animowanego gif spowoduje znaczną poprawę jakości obrazu.

Coś takiego powinno ci działać:

 ffmpeg -framerate 1/2 -i img%04d.png -c:v libx264 -r 30 out.mp4
  • -framerate 1/2: Ustawia liczbę klatek na sekundę na 1/2 FPS lub 2 sekundy na klatkę.
  • -i img%04d.png: To mówi ffmpeg czytać pliki img0000.pngchociaż img9999.png.
  • -c:v libx264: Użyj kodeka wideo libx264.
    • Możesz tutaj określić parametry kompresji wideo, jeśli chcesz:
    • -crf <number>: Ustawienie jakości. 0 do 51. 23 jest wartością domyślną. 0 to prawdziwe bezstratne kodowanie, które będzie dość dużą przepustowością. 18 jest prawie wizualnie bezstratny.
  • -r 30: Ustaw wyjściową liczbę klatek na sekundę na 30 FPS. Każdy z obrazów wejściowych zostanie zduplikowany, aby uzyskać dane wyjściowe określone w tym miejscu. Możesz pozostawić ten parametr wyłączony, a plik wyjściowy będzie miał wejściową liczbę klatek na sekundę, ale wynikowy film nie wyświetlał się poprawnie, gdy próbowałem go teraz.
  • out.mp4: Nazwa pliku wyjściowego.

Referencje:

David Yaw
źródło
1
Ładne rozszerzenie odpowiedzi Frantique z dnia poprzedniego.
Elder Geek
Oto prosty test porównawczy ffmpeg vs ImageMagick z konkretnymi danymi testowymi: askubuntu.com/questions/648244/...
Ciro Santilli 事件 改造 中心 法轮功 六四 事件
11

Osobiście uruchomiłbym go tylko na ograniczonej liczbie plików zamiast na raz. Na przykład coś takiego:

#!/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
źródło
8

Użyj, -limit memory 1GiBaby ograniczyć ilość pamięci convert.

Tysiące zdjęć stworzyłyby ogromny plik GIF, który większość komputerów będzie miała problem z wyświetleniem. Moje animowane pliki GIF trzymam poniżej 200 obrazów, jeśli to możliwe. Im mniej, tym lepiej. Jeśli numerujesz zdjęcia, to polecenie usunie obrazy nieparzyste rm *[13579].png.

Oto mój typowy proces tworzenia animowanego GIF ze sceny filmowej:

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
źródło
1
Dziękujemy, to rozwiązanie działa dobrze. Konieczne może być również zwiększenie limitów pamięci w /etc/ImageMagick-6/policy.xml, patrz github.com/ImageMagick/ImageMagick/issues/…, aby uzyskać więcej informacji
Louis Gagnon
4

Mógłbym użyć innego otwartego formatu, jeśli .gifnie jest obsługiwany

Być może APNG może ci się przydać . Jest obsługiwany przez niektóre przeglądarki , w tym Firefox, ale w tej chwili z wyjątkiem Chrome i IE. Ponieważ jest to tylko rozszerzenie PNG, bardzo łatwo jest przekonwertować PNG na APNG. Apngasm narzędzie może to zrobić. Ale format jest tak prosty, że niedawno napisałem asembler APNG dla Sage. Dostosowanie tego kodu byłoby alternatywą.

MvG
źródło
Chciałbym również zauważyć, że APNG jest niestandardowy i pomimo tego, że istnieje od 7 lat, jest nadal bardzo niejasny.
Pharap,
W przypadku demonstracji naukowej, w której możesz wybrać przeglądarkę, której używasz, nadal może to być proste i niezawodne rozwiązanie.
MvG,
To zależy od tego, kto musi obejrzeć pokaz. Rozdawanie kopii widzom nie byłoby zbyt dobre, a następnie dwie trzecie musiało wyjść i pobrać Firefoksa, aby go zobaczyć. Nie takie wrażenie, jakie chciałbym zrobić, gdybym zrobił ważną naukową demonstrację. Jeśli ma to być postrzegane tylko jako część demonstracji, to wystarczy, ale może nie być odpowiednie w innych sytuacjach.
Pharap
3

Jeśli masz tysiące png-s, format anigif jest dziwny. Zrobiłbym to w ten sposób, używając avconv:

 avconv -i "%d.png" -r 25 -c:v libx264 -crf 20 -pix_fmt yuv420p animated.mov
Frantique
źródło
Takie podejście ma tę dodatkową zaletę, że można później multipleksować w lektorze lub muzyce, co jest niemożliwe w przypadku formatu Graphics Interchange Format.
Starszy Geek
2

gifsicle to narzędzie wiersza polecenia do obsługi animacji GIF. Jeśli chcesz wymienić pamięć na szybkość, możesz użyć przełącznika --conserve-memory.

kodhead
źródło
Ujmę to w ten sposób: gifsicle już ma mniejszą powierzchnię niż ImageMagick - jeśli okaże się, że nadal używa zbyt dużo pamięci dla zadania pod ręką, a następnie można użyć --conserve pamięci
codehead
Och, myślę, że źle odczytałem to, co mówiłeś, że przełącznik zużyłby więcej pamięci, co nie ma większego sensu. nieważne.
curiousdannii
2

Oprócz innych odpowiedzi: ponieważ chcesz utworzyć plik GIF, zakładam, że chcesz wyświetlić obraz na stronie internetowej. Jeśli tak, nie zawracałbym sobie głowy konwersją twoich plików PNG. Wystarczy wyszukać w Google „pokaz slajdów javascript” i użyć jednego z milionów darmowych skryptów. Lub napisz własne, to naprawdę trywialne.

Korzyści z robienia tego w ten sposób to:

  • w przeglądarce ładowany jest tylko jeden obraz, pokaz slajdów rozpoczyna się szybko i nie zajmuje dużo pamięci RAM na komputerze użytkownika.

  • rozwiązanie skaluje się do milionów zdjęć. Lub miliardy, jeśli jesteś wystarczająco cierpliwy, aby je wszystkie oglądać :)

  • Możesz dodać do swojej strony elementy sterujące, aby wstrzymywać, przewijać do tyłu, zmieniać opóźnienie lub przechodzić do określonej klatki.

Siergiej
źródło
Dziękuję Siergiej. W rzeczywistości nie jest to wyświetlane na stronie internetowej. +1 za pomysł.
dotancohen,