Автоматизация и разработка

Пакетная конвертация изображений с FFmpeg: практическое руководство

5 мин.

У вас 500 PNG-скриншотов, которые нужно перевести в WebP для сайта. Или папка с TIFF-экспортами из Lightroom, которые нужно сделать JPG. Или сотни фото товаров в формате, который не принимает CMS. Конвертировать их по одному — не вариант.

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

Зачем использовать FFmpeg для изображений

Большинство разработчиков использует ImageMagick для пакетной работы с изображениями — и это вполне обоснованный выбор. У FFmpeg есть свои преимущества: он уже установлен у тех, кто работает с видео; поддерживает широкий спектр форматов; естественно вписывается в скрипты и CI-пайплайны, которые уже используют FFmpeg для других задач. Для конвертации между распространёнными веб-форматами — JPG, PNG, WebP, AVIF — он даёт отличные результаты простыми командами.

Для RAW-форматов камеры (CR2, NEF, ARW) лучше использовать darktable или RawTherapee — поддержка RAW в FFmpeg ограничена. Для всего остального — один из самых быстрых вариантов.

Установка FFmpeg

bash
# macOS
brew install ffmpeg

# Ubuntu / Debian
sudo apt install ffmpeg

# Windows (через Chocolatey)
choco install ffmpeg

Проверка установки:

bash
ffmpeg -version

Базовая структура команды

Каждая команда пакетной конвертации строится по одному принципу. На Linux и macOS используется цикл оболочки, на Windows — цикл for в командной строке или foreach в PowerShell.

Ключевое правило: никогда не перезаписывайте исходные файлы. Всегда пишите результат в отдельную директорию. Все примеры ниже следуют этому принципу.

Пакетная конвертация PNG в JPG

Самая распространённая конвертация. PNG → JPG значительно уменьшает размер файла для фотографий.

bash
# Linux / macOS — конвертация всех PNG в текущей директории
mkdir -p output
for f in *.png; do
  ffmpeg -i "$f" -q:v 2 "output/${f%.png}.jpg"
done
bash
# Windows Командная строка
mkdir output
for %f in (*.png) do ffmpeg -i "%f" -q:v 2 "output/%~nf.jpg"
bash
# Windows PowerShell
New-Item -ItemType Directory -Force output
Get-ChildItem *.png | ForEach-Object {
  ffmpeg -i $_.FullName -q:v 2 "output/$($_.BaseName).jpg"
}

Флаг -q:v 2 управляет качеством. Шкала от 1 (лучшее качество, большой файл) до 31 (низкое качество, маленький файл). Практический диапазон для веба — 2–5:

Значение -q:vКачествоТипичное использование
1–2Почти без потерьПечать, архивирование
3–5Высокое качествоВеб-фотографии
6–10Среднее качествоПревью, миниатюры
11+Низкое качествоИзбегать в большинстве случаев

Пакетная конвертация JPG в WebP

WebP обычно даёт файлы на 25–35% меньше, чем JPG при аналогичном воспринимаемом качестве. Конвертация существующей библиотеки JPG в WebP — одна из самых эффективных оптимизаций производительности сайта.

bash
# Linux / macOS — WebP с потерями, качество 85
mkdir -p output
for f in *.jpg *.jpeg; do
  [ -f "$f" ] || continue
  ffmpeg -i "$f" -quality 85 "output/${f%.*}.webp"
done
bash
# Linux / macOS — WebP без потерь (для графики, скриншотов, логотипов)
mkdir -p output
for f in *.png; do
  ffmpeg -i "$f" -lossless 1 "output/${f%.png}.webp"
done
bash
# Windows Командная строка
mkdir output
for %f in (*.jpg) do ffmpeg -i "%f" -quality 85 "output/%~nf.webp"

Рекомендация по качеству: 80–85 — оптимальный диапазон для фотографий. Значения выше 90 дают файлы почти такого же размера, как JPG, при минимальной визуальной разнице. Для логотипов и графики с текстом используйте WebP без потерь.

Пакетная конвертация в PNG

Конвертация в PNG сохраняет полное качество — полезно для создания промежуточного лосслесс-формата или подготовки файлов к дальнейшей обработке.

bash
# Linux / macOS — все JPG в PNG
mkdir -p output
for f in *.jpg *.jpeg; do
  [ -f "$f" ] || continue
  ffmpeg -i "$f" "output/${f%.*}.png"
done
bash
# Linux / macOS — все WebP в PNG
mkdir -p output
for f in *.webp; do
  ffmpeg -i "$f" "output/${f%.webp}.png"
done

Для PNG флаг качества не нужен — формат без потерь, FFmpeg по умолчанию кодирует с максимальным качеством.

Пакетная конвертация смешанных форматов

Когда папка содержит смесь JPG, PNG и WebP и нужно всё привести к одному формату:

bash
# Linux / macOS — всё в JPG
mkdir -p output
for f in *.jpg *.jpeg *.png *.webp *.tiff *.bmp; do
  [ -f "$f" ] || continue
  ffmpeg -i "$f" -q:v 3 "output/${f%.*}.jpg"
done
bash
# Windows Командная строка — JPG, PNG и WebP в JPG
mkdir output
for %f in (*.jpg *.png *.webp) do ffmpeg -i "%f" -q:v 3 "output/%~nf.jpg"

Изменение размера при конвертации

FFmpeg умеет изменять размер и конвертировать за один проход через фильтр -vf scale. Это значительно быстрее, чем конвертировать и потом изменять размер отдельно.

bash
# Уменьшить все PNG до ширины 1080px, конвертировать в JPG
# Высота масштабируется пропорционально (-1 сохраняет соотношение сторон)
mkdir -p output
for f in *.png; do
  ffmpeg -i "$f" -vf scale=1080:-1 -q:v 3 "output/${f%.png}.jpg"
done
bash
# Ограничить длинную сторону до 800px (только уменьшение, не увеличение)
mkdir -p output
for f in *.jpg; do
  ffmpeg -i "$f" -vf "scale='min(800,iw)':'min(800,ih)':force_original_aspect_ratio=decrease" \
    -q:v 3 "output/${f%.jpg}.jpg"
done
bash
# Создать квадратные миниатюры (обрезка по центру, затем масштаб)
mkdir -p output
for f in *.jpg; do
  ffmpeg -i "$f" -vf "crop='min(iw,ih)':'min(iw,ih)',scale=200:200" \
    "output/${f%.jpg}_thumb.jpg"
done

Рекурсивная обработка с поддиректориями

Базовый цикл обрабатывает только файлы в текущей директории. Для рекурсивной обработки с сохранением структуры папок:

bash
# Linux / macOS — рекурсивно, сохранить структуру директорий
find . -name "*.png" -not -path "./output*" | while read f; do
  output="output/${f#./}"
  mkdir -p "$(dirname "$output")"
  ffmpeg -i "$f" -q:v 3 "${output%.png}.jpg"
done
bash
# Linux / macOS — плоский вывод (все файлы в одну папку)
mkdir -p output
find . -name "*.png" -exec sh -c \
  'ffmpeg -i "$1" -q:v 3 "output/$(basename "${1%.png}").jpg"' _ {} \;

Параллельная обработка для ускорения

По умолчанию цикл обрабатывает один файл за раз. На многоядерном процессоре можно запустить конвертации параллельно:

bash
# Linux / macOS — параллельная конвертация через xargs (4 одновременных задачи)
mkdir -p output
ls *.png | xargs -P 4 -I {} sh -c 'ffmpeg -i "$1" -q:v 3 "output/${1%.png}.jpg"' _ {}
bash
# Через GNU parallel
mkdir -p output
parallel ffmpeg -i {} -q:v 3 output/{.}.jpg ::: *.png

На 8-ядерном процессоре с SSD параллельная обработка обычно сокращает время конвертации в 3–5 раз. На HDD дисковый ввод-вывод становится узким местом и параллелизм помогает меньше.

Индикатор прогресса

Для больших пакетов полезно знать, насколько далеко продвинулась конвертация:

bash
# Linux / macOS — показывать прогресс
total=$(ls *.png | wc -l)
count=0
mkdir -p output
for f in *.png; do
  count=$((count + 1))
  echo "Конвертирую $count/$total: $f"
  ffmpeg -loglevel quiet -i "$f" -q:v 3 "output/${f%.png}.jpg"
done
echo "Готово. Конвертировано файлов: $count"

Флаг -loglevel quiet подавляет собственный вывод FFmpeg — остаются только ваши сообщения о прогрессе.

Обработка ошибок

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

bash
# Linux / macOS — пропускать сбойные файлы, логировать ошибки
mkdir -p output
error_log="errors.txt"
> "$error_log"

for f in *.jpg *.jpeg *.png *.webp; do
  [ -f "$f" ] || continue
  if ffmpeg -loglevel error -i "$f" -quality 85 "output/${f%.*}.webp" 2>>"$error_log"; then
    echo "✓ $f"
  else
    echo "✗ $f (см. $error_log)"
  fi
done

Справочник команд

КонвертацияКоманда (Linux/macOS)Примечание
Все PNG → JPGfor f in *.pngdo ffmpeg -i "$f" -q:v 3 output/${f%.png}.jpg
Все JPG → WebPfor f in *.jpgdo ffmpeg -i "$f" -quality 85 output/${f%.jpg}.webp
Все JPG → PNGfor f in *.jpgdo ffmpeg -i "$f" output/${f%.jpg}.png
Все → WebP без потерьfor f in *.pngdo ffmpeg -i "$f" -lossless 1 output/${f%.png}.webp
Изменить размер + конвертироватьfor f in *.jpgdo ffmpeg -i "$f" -vf scale=1080:-1 -q:v 3 output/${f%.jpg}.jpg

Когда FFmpeg — не лучший инструмент

RAW-форматы камеры (CR2, NEF, ARW, DNG) — поддержка ограничена. Используйте darktable или RawTherapee.

Кодирование AVIF — FFmpeg может создавать AVIF через -c:v libaom-av1, но это очень медленно без аппаратного ускорения. Для пакетной конвертации в AVIF libavif или Squoosh CLI быстрее.

HEIC/HEIF — поддержка зависит от сборки FFmpeg. На macOS через Homebrew обычно работает. На Linux может потребоваться установка дополнительных библиотек.

Сохранение ICC-профилей цвета — FFmpeg не всегда сохраняет встроенные цветовые профили. Для цветокритичной работы ImageMagick или ExifTool надёжнее.

Нужно конвертировать несколько файлов разово? Командные инструменты требуют времени на настройку. Для единичных конвертаций онлайн-инструмент вроде FastConvert быстрее — без установки, без скриптов.

Часто задаваемые вопросы

По умолчанию FFmpeg не копирует EXIF-метаданные (настройки камеры, GPS, дату). Для сохранения метаданных добавьте -map_metadata 0: ffmpeg -i input.jpg -map_metadata 0 -q:v 3 output.jpg. Некоторые поля могут всё равно потеряться в зависимости от выходного формата.

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

Используйте PNG как выходной формат (без потерь) или -lossless 1 для WebP. Для JPG -q:v 1 или -q:v 2 максимально близко к без потерь, но сжатие всё равно присутствует.

Зависит от сборки FFmpeg. На macOS через Homebrew обычно работает. На Linux может потребоваться сборка FFmpeg с поддержкой libheif. Протестируйте один файл перед запуском пакетной обработки: ffmpeg -i test.heic test.jpg

Добавьте -y для автоматической перезаписи или -n для пропуска существующих файлов. Пример: ffmpeg -n -i input.png output.jpg (пропускает, если output.jpg уже существует).

Итог

Пакетная конвертация изображений через FFmpeg строится на простом цикле: итерация по исходным файлам, запуск команды конвертации для каждого, запись результата в отдельную директорию. Команды в этом руководстве покрывают самые распространённые сценарии — PNG в JPG, JPG в WebP, смешанные форматы, изменение размера вместе с конвертацией, рекурсивная обработка директорий — на всех трёх операционных системах.

Два момента, которые часто упускают: всегда тестируйте на небольшом пакете перед запуском на всей библиотеке, и используйте -loglevel quiet в сочетании с логом ошибок — так вы узнаете, какие файлы не удалось обработать, не разбирая подробный вывод FFmpeg.

Нужно конвертировать изображения без командной строки? Попробуйте конвертер изображений FastConvert — бесплатно, без регистрации.

Поделиться