Конвертируйте тысячи .png в анимированные .gif, `convert` использует слишком много памяти

29

Многие из вопросов, спрашивающих, как создать анимированный GIF из набора изображений PNG, предлагают использовать вариант команды ImageMagick convert:

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

Тем не менее, у меня есть несколько тысяч изображений, и, таким образом, я convertиспользую всю свою память, меняю местами и затем вылетаю Какое альтернативное программное обеспечение существует, которое больше заботится о памяти? Я мог бы использовать другой открытый формат, если .gifон не поддерживается, и я предпочитаю инструмент CLI.

dotancohen
источник
1
Как насчет разделения файлов * .png на управляемые куски? Допустим, все имена файлов начинаются с цифры, а затем convert -delay 2 -loop 0 0*.png animated.gifпреобразуются только в те файлы, которые начинаются с «0». И так далее.
Джос
2
Таким образом, каждый .png порядка 1 Мб? В этом случае все, что я могу придумать, - это сначала преобразовать файлы .png в более низкое разрешение или глубину цвета, чтобы сделать их меньше.
Иос
10
Вы говорите, что можете использовать другой открытый формат. Мне кажется, что GIF не самый лучший формат для тысяч кадров. Вы рассматривали кодирование видео с Ogg Theora вместо этого?
rekado
1
Возможно, взгляните на gifsicle , если вы действительно хотите использовать GIF? (Хотя, как уже говорили другие, это не то, для чего был создан GIF; OGG был бы лучшим выбором.)
wchargin
1
Число рейнольдса «куда идет вся память»: 65 Кбайт - размер файла сжатого изображения. В несжатом виде изображение занимает примерно 4 x ширина x высота байт, поэтому для изображения 1024x768 потребуется ~ 3 МБ ОЗУ. Умножьте это на «несколько тысяч», и вы увидите, куда уходит память ...
Сергей

Ответы:

33

Похоже, вы пытаетесь сделать видео. Если это так, то я бы использовал правильный формат видео.

В этом случае я бы использовал ffmpeg для преобразования отдельных файлов PNG в видео H.264. Поскольку ffmpeg предназначен для работы с видео, которое может длиться часами, у вас не должно возникнуть проблем с тысячами изображений. Использование H.264 вместо анимированного GIF приведет к значительному улучшению качества изображения.

Нечто подобное должно работать для вас:

 ffmpeg -framerate 1/2 -i img%04d.png -c:v libx264 -r 30 out.mp4
  • -framerate 1/2: Это устанавливает частоту кадров в половину FPS, или 2 секунды на кадр.
  • -i img%04d.png: Это говорит FFmpeg для чтения файлов , img0000.pngхотя img9999.png.
  • -c:v libx264: Используйте видеокодек libx264.
    • Вы можете указать параметры сжатия видео здесь, если вам нравится:
    • -crf <number>: Настройка качества. От 0 до 51. 23 по умолчанию. 0 - это истинное кодирование без потерь, которое будет иметь достаточно высокую пропускную способность. 18 почти без визуальных потерь.
  • -r 30: Установите выходную частоту кадров 30 кадров в секунду. Каждое из входных изображений будет продублировано, чтобы сделать вывод, который вы указали здесь. Вы можете оставить этот параметр отключенным, и выходной файл будет с входной частотой кадров, но полученный фильм не отображался должным образом, когда я попробовал его только сейчас.
  • out.mp4: Имя выходного файла.

Ссылки:

Дэвид Йо
источник
1
Хорошее расширение Frantique ответа от предыдущего дня.
Старейшина Компьютерщик
Вот простой тест ffmpeg против ImageMagick с конкретными данными испытаний: askubuntu.com/questions/648244/…
Сиро Сантилли 23 改造 中 at 法轮功 六四 事件
11

Лично я бы просто запустил его на ограниченном количестве файлов вместо всех сразу. Например, что-то вроде этого:

#!/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
источник
8

Используйте -limit memory 1GiBдля ограничения объема convertиспользуемой памяти .

Тысячи изображений создадут огромный GIF-файл, который большинство компьютеров будет стараться показать. Я держу свои анимированные GIF-изображения ниже 200 изображений, когда это возможно. Чем меньше, тем лучше. Если вы пронумеруете свои изображения, эта команда удалит нечетные изображения rm *[13579].png.

Итак, вот мой типичный рабочий процесс для создания анимированного GIF из сцены фильма:

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
источник
1
Спасибо, это решение работает хорошо. Он также может быть необходимо увеличить допустимые пределы памяти в /etc/ImageMagick-6/policy.xml см github.com/ImageMagick/ImageMagick/issues/... для получения дополнительной информации
Луи Ганьон
4

Я мог бы использовать другой открытый формат, если .gifне поддерживается

Возможно, APNG пригодится вам. Он поддерживается некоторыми браузерами , включая Firefox, но на данный момент, за исключением Chrome и IE. Поскольку это просто расширение PNG, конвертировать PNG в APNG очень просто. Инструмент apngasm может сделать это. Но формат настолько прост, что недавно я сам написал сборщик APNG для Sage. Адаптация этого кода была бы альтернативой.

MVG
источник
Я также хотел бы отметить, что APNG является нестандартным и, несмотря на то, что он существует около 7 лет, все еще очень неясен.
Pharap
Для научной демонстрации, где вы можете выбрать браузер, используемый для него, это может быть простым и надежным решением.
MvG
Это зависит от того, кто должен смотреть демонстрацию. Было бы не очень хорошо раздавать копии зрителям, и тогда две трети должны уйти и загрузить Firefox просто для просмотра. Не то впечатление, которое я хотел бы произвести, если бы я делал важную научную демонстрацию. Если оно предназначено только для демонстрации, то достаточно справедливо, но оно может не подходить для других ситуаций.
Pharap
3

Если у вас есть тысячи PNG, формат anigif странный. Я бы сделал это таким образом, используя avconv:

 avconv -i "%d.png" -r 25 -c:v libx264 -crf 20 -pix_fmt yuv420p animated.mov
Frantique
источник
Этот подход имеет дополнительное преимущество, заключающееся в том, что вы можете позже использовать звук закадрового или музыкального звука, что невозможно с графическим форматом обмена.
Старейшина Компьютерщик
2

gifsicle - это утилита командной строки для обработки анимации GIF. Если вы хотите обменять память на скорость, вы можете использовать ее ключ --conserve-memory.

codehead
источник
Позвольте мне выразиться так: gifsicle уже занимает меньше места, чем ImageMagick - если вы обнаружите, что он все еще использует слишком много памяти для выполнения задачи, то вы можете использовать --conserve-memory
codehead
О, я думаю, что я неправильно понял, что вы говорили, что коммутатор будет использовать больше памяти, что не имеет особого смысла. не берите в голову.
curiousdannii
2

В дополнение к другим ответам: поскольку вы хотите создать GIF-файл, я предполагаю, что вы хотите отобразить изображение на веб-странице. Если это так, я бы не стал конвертировать ваши PNG вообще. Просто Google для "слайд-шоу Javascript" и использовать один из миллионов бесплатных сценариев. Или написать свой, это действительно тривиально.

Преимущества этого метода:

  • в браузер загружается только одно изображение, слайд-шоу запускается быстро и не занимает много ОЗУ на компьютере пользователя.

  • решение масштабируется до миллионов изображений. Или миллиарды, если вы достаточно терпеливы, чтобы посмотреть их все :)

  • Вы можете добавить элементы управления на свою страницу, чтобы приостановить, перемотать назад, изменить задержку или перейти к определенному кадру.

Сергей
источник
Спасибо, Сергей. На самом деле это не для отображения на веб-странице. +1 за идею, хотя.
dotancohen