Как я могу изменить размер анимированного GIF-файла с помощью ImageMagick?

Вопрос или проблема

Я хочу изменить размер такого анимированного 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.

Оцените материал
Добавить комментарий

Капча загружается...