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


29

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

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

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


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

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

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

4

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

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


Я также хотел бы отметить, что 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

Этот подход имеет дополнительное преимущество, заключающееся в том, что вы можете позже использовать звук закадрового или музыкального звука, что невозможно с графическим форматом обмена.
— Старейшина Компьютерщик

2

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


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

О, я думаю, что я неправильно понял, что вы говорили, что коммутатор будет использовать больше памяти, что не имеет особого смысла. не берите в голову.
— curiousdannii

2

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

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

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

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

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


Спасибо, Сергей. На самом деле это не для отображения на веб-странице. +1 за идею, хотя.
— dotancohen
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.