Вопрос или проблема
Я хочу изменить размер такого анимированного GIF-файла do.gif
Если я выполню convert do.gif -resize 24x24\! do-24.gif
, я получу изменённый размер в do-24.gif, но он будет не анимированным
Как правильно изменить его размер, чтобы сохранить ту же анимацию?
Сначала выполните:
convert do.gif -coalesce temporary.gif
Затем
convert -size <оригинальный размер> temporary.gif -resize 24x24 smaller.gif
Я искал решение с помощью ImageMagick, так как знаком с ним, но в конце концов выбрал рекомендацию @sam использовать gifsicle
. Это сделало именно то, что мне нужно, без хлопот.
Можно оптимизировать размер полученного файла столькими способами, но я просто уменьшил размер и уменьшил количество цветов. Сработало как нельзя лучше:
gifsicle --resize 48x48 --colors 16 original.gif > smaller.gif
-coalesce
+ -deconstruct
После -coalesce
, вероятно, вы захотите добавить -deconstruct
:
convert in.gif -coalesce -resize 256x -deconstruct out-deconstruct.gif
Основная причина проблемы в том, что ваш входной GIF был должным образом оптимизирован: GIF позволяет следующему кадру быть просто изменённым прямоугольником из предыдущего с смещением.
-coalesce
затем расширяет все кадры до оригинального размера, что делает изменение размера возможным, но он не сжимает кадры снова, как ваш входной образ: для этого нужен -deconstruct
!
Используя тестовые данные из этого ответа: Как создать анимированный gif из неподвижных изображений (предпочтительно через командную строку)?, мы можем это явно увидеть с помощью identify
:
$ identify out-convert.gif | head -n 3
out-convert.gif[0] GIF 1024x1024 1024x1024+0+0 8-бит sRGB 256c 16.7865MiB 0.020u 0:00.019
out-convert.gif[1] GIF 516x516 1024x1024+252+257 8-бит sRGB 256c 16.7865MiB 0.030u 0:00.019
out-convert.gif[2] GIF 515x520 1024x1024+248+257 8-бит sRGB 256c 16.7865MiB 0.030u 0:00.019
$ convert out-convert.gif -resize 256x out.gif
$ identify out.gif | head -n 3
out.gif[0] GIF 256x256 256x256+0+0 8-бит sRGB 256c 5.0479MiB 0.000u 0:00.009
out.gif[1] GIF 256x256 256x256+125+128 8-бит sRGB 256c 5.0479MiB 0.000u 0:00.009
out.gif[2] GIF 256x258 256x256+123+128 8-бит sRGB 256c 5.0479MiB 0.000u 0:00.009
$ convert out-convert.gif -coalesce -resize 256x out-coalesce.gif
$ identify out-coalesce.gif | head -n 3
out-coalesce.gif[0] GIF 256x256 256x256+0+0 8-бит sRGB 256c 1.97683MiB 0.010u 0:00.009
out-coalesce.gif[1] GIF 256x256 256x256+0+0 8-бит sRGB 256c 1.97683MiB 0.010u 0:00.009
out-coalesce.gif[2] GIF 256x256 256x256+0+0 8-бит sRGB 256c 1.97683MiB 0.010u 0:00.009
$ convert out-convert.gif -coalesce -resize 256x -deconstruct out-deconstruct.gif
$ identify out-deconstruct.gif | head -n 3
out-deconstruct.gif[0] GIF 256x256 256x256+0+0 8-бит sRGB 256c 1.87942MiB 0.010u 0:00.010
out-deconstruct.gif[1] GIF 135x135 256x256+60+61 8-бит sRGB 256c 1.87942MiB 0.010u 0:00.010
out-deconstruct.gif[2] GIF 135x136 256x256+59+61 8-бит sRGB 256c 1.87942MiB 0.010u 0:00.010
out.gif
out-coalesce.gif
out-deconstruct.gif
Во-первых, мы видим, как входной файл out-convert.gif
на самом деле был сжат, так как кадр 2 имеет размер всего 516x516
с смещением 252+257
, в то время как полный кадр 1 имеет размер 1024x1024
.
Затем, если мы сравним три преобразования:
-
out.gif
: Все кадры имеют размер256x256
или больше, и размер около 5MiB, TODO почему?Визуально неверно, так как эти примерно
256x256
кадры имеют ненулевое смещение, например,125+128
для кадра 2! -
out-coalesce.gif
: все кадры имеют размер256x256
и имеют правильное смещение0+0
.Вывод выглядит визуально корректно, но размер выходного файла 2.0 MiB, что больше, чем
out-deconstruct.gif
-
out-deconstruct.gif
: сжатые кадры, итоговый размер выходного файла 1.9 MiB.Не значительно меньше, чем
out-coalesce.gif
, но я думаю, это просто потому, что черный фон хорошо сжимается, и в общем это может быть очень значимо.
ffmpeg и gifsicle
Я также попробовал следующие команды:
ffmpeg -i out-convert.gif -vf scale=256:-1 out-ffmpeg-small.gif
gifsicle --resize 256x256 out-convert.gif > out-gifsicle.gif
И оба выдали ещё меньший корректно выглядящий выходной файл размером 1.5 MiB.
См. также: Как создать анимированный gif из неподвижных изображений (предпочтительно через командную строку)?
TODO: почему они могут сделать его меньше, чем convert
? Просто выбирают ли они лучшие минимальные прямоугольники для дифференцирования или что-то другое?
Тестировалось на Ubuntu 18.10, ffmpeg 4.0.2-2, ImageMagick 6.9.10-8.
wget https://upload.wikimedia.org/wikipedia/commons/f/f9/STS-132_Liftoff_Space_Shuttle_Atlantis.ogv
ffmpeg -i STS-132_Liftoff_Space_Shuttle_Atlantis.ogv -r 15 -vf scale=512:-1 \
-ss 00:00:17 -to 00:00:22 STS-132_Liftoff_Space_Shuttle_Atlantis.gif
Ответ или решение
Для изменения размера анимированного GIF-файла с помощью ImageMagick следуйте приведённым ниже шагам, которые обеспечат сохранение анимации в итоговом файле.
Этап 1: Подготовка файлов
Сначала вам нужно использовать команду -coalesce
, которая разворачивает каждый кадр GIF-файла. Это важно, чтобы упростить процесс изменения размера, поскольку при этом каждый кадр становится независимым.
convert do.gif -coalesce temporary.gif
Этап 2: Изменение размера
Теперь, когда каждый кадр независим, вы можете изменить размер каждого кадра. Используйте следующую команду, чтобы изменить размер до желаемых параметров (например, 24×24):
convert temporary.gif -resize 24x24 smaller.gif
Этап 3: Восстановление анимации
После изменения размера вам нужно восстановить анимацию. Для этого используется команда -deconstruct
, которая переупаковывает кадры, сохраняя их анимацию.
convert smaller.gif -deconstruct output.gif
Получение итогового файла
Теперь файл output.gif
будет содержать анимированное изображение с изменённым размером и сохранённой анимацией.
Дополнительная оптимизация
Если вы хотите дополнительно оптимизировать размер файла, можете воспользоваться инструментом gifsicle
, который обеспечивает дополнительные параметры для уменьшения веса анимированных GIF-файлов. Например, вы можете использовать следующую команду для оптимизации:
gifsicle --resize 24x24 --colors 16 do.gif > optimized.gif
Заключение
Следуя этой инструкции, вы сможете эффективно изменить размер анимированного GIF-файла, сохранив его анимацию. Сначала используйте команды -coalesce
и -resize
, затем не забудьте о восстановлении анимации с помощью -deconstruct
. Это обеспечит качественный результат, который вы можете дополнительно оптимизировать с помощью gifsicle
.