Растровые форматы: JPG, JPEG, PNG и WebP; как они хранят изображение и что выбрать?
Один и тот же рисунок может занять считанные килобайты в PNG и заметно больше в JPEG. А с фотографией всё может оказаться наоборот. Дело не только в настройке «качество»: форматы по-разному представляют пиксели, и содержимое изображения влияет на результат не меньше, чем его разрешение.
JPG и JPEG — один формат?
Да. .jpg и .jpeg — разные расширения для обычного JPEG; оба обычно имеют тип image/jpeg. Переименование файла ничего не перекодирует и не меняет качество.
Техническая оговорка: стандарт JPEG включает и редко используемые режимы без потерь. Дальше под JPEG я имею в виду привычный фотографический JPEG с потерями, который обычно встречается в файлах .jpg и .jpeg.
Что попадает в файл
JPEG: меньше данных ценой неточных пикселей
Обычный JPEG часто преобразует RGB в яркостную составляющую и две цветоразностные. При настройке, например, 4:2:0 цветовые составляющие сохраняются с меньшим пространственным разрешением: на цвете можно сэкономить, пока яркостные детали остаются различимыми. Такая субдискретизация распространена, но не обязательна для каждого JPEG.
Затем изображение обрабатывается блоками по 8 × 8 значений. Дискретное косинусное преобразование (DCT) переводит данные блока из значений пикселей в набор частотных коэффициентов. Квантование огрубляет эти коэффициенты; после него восстановить исходные значения уже нельзя. Оставшиеся числа кодируются компактнее, в распространённом варианте — с помощью кодов Хаффмана.
На фотографии небольшая ошибка часто почти незаметна. На мелком тексте, тонкой линии и резкой границе она проявляется как размытие, ореолы или блоки. Для фотографии в оттенках серого JPEG может хранить один компонент вместо трёх цветовых: отсутствие цвета само по себе не обязывает сохранять три одинаковых канала. У привычного JPEG нет обычного альфа-канала для прозрачности.
PNG: точные пиксели, фильтры и DEFLATE
PNG начинается с сигнатуры и состоит из блоков, или chunks. IHDR задаёт размеры, глубину и тип цвета; PLTE содержит палитру, если изображение индексированное; один или несколько IDAT несут сжатые данные; IEND завершает поток.
Перед сжатием строки пикселей проходят обратимый фильтр. Он записывает значения относительно соседних данных так, чтобы повторения было легче сжать. Затем применяется zlib/DEFLATE. И фильтр, и сжатие обратимы: при декодировании получаем те же значения пикселей, которые передали кодировщику.
PNG умеет хранить серый цвет с глубиной 1, 2, 4, 8 или 16 бит на отсчёт, RGB, палитру до 256 цветов, а также варианты с прозрачностью.
PNG с фотографией тоже остаётся без потерь. Просто плавные переходы, шум матрицы и множество разных цветов обычно оставляют меньше повторяемых данных для компрессора, чем плоская графика. Поэтому цветная фотография в PNG нередко занимает больше места, чем визуально приемлемый JPEG. Сравнивать размеры без учёта потерь в JPEG здесь нечестно.
WebP: два разных способа сжатия в одной оболочке
Файл WebP — контейнер RIFF с данными изображения и, при необходимости, блоками для прозрачности, цветового профиля, метаданных или анимации. Расширение .webp не говорит, каким способом сжаты пиксели:
WebP с потерями использует внутрикадровое кодирование VP8: предсказывает содержимое блоков по соседям, кодирует остаток преобразованиями и квантованием. Цвет хранится в 8-битном Y′CbCr 4:2:0. Прозрачность тоже возможна: цвет может быть сжат с потерями, а альфа-канал — отдельно.
WebP без потерь применяет обратимые преобразования, предсказание, повторное использование фрагментов и ранее встреченных цветов, затем энтропийное кодирование. Этот режим работает с 8-битными компонентами RGBA.
У WebP lossless есть неочевидный нюанс: при настройках по умолчанию некоторые кодировщики меняют RGB-значения у полностью прозрачных пикселей ради лучшего сжатия. На экране это не видно, но при побайтовой проверке декодированных RGBA-значений различие обнаружится. В libwebp для сохранения таких значений предусмотрена настройка exact.
Быстрый выбор по типу изображения
Исходные | С чего начать | Почему |
|---|---|---|
Фотография для сайта, прозрачность не нужна | WebP с потерями; JPEG для совместимости с нужными системами | Можно уменьшить объём, если неприемлемо небольшое изменение изображения |
Цветная фотография, важна точность каждого пикселя | PNG; для 8-битной версии также cравнить WebP lossless | Сжатие без потерь; оценивать размер стоит после проверки одинаковых пикселей |
Скриншот интерфейса, код, диаграмма с текстом | PNG или WebP lossless | Резкие края и точные цвета остаются без артефактов квантования |
Двухцветный чертёж или маска | 1-битный PNG; сравнить с WebP lossless | Можно кодировать два значения компактно, сохраняя точные границы |
Фотография в градациях серого | Серый JPEG/WebP lossy, если потери допустимы; PNG при требовании точных значений | Число каналов меньше, но текстура и шум всё равно влияют на размер |
Растровый логотип с прозрачным фоном | PNG или WebP lossless | Сохраняются чёткие контуры и прозрачность |
16-битный мастер для обработки | PNG среди перечисленных форматов | Не нужно понижать глубину до 8 бит на канал |
Слово «без потерь» относится к данным, поступившим в кодировщик, а не ко всей истории картинки. Перевод 16 бит в 8, сокращение палитры или изменение цветового профиля перед сохранением могут изменить изображение и при экспорте в PNG. Пересохранение старого JPEG в PNG тоже не восстанавливает детали, однажды удалённые JPEG-кодированием.
Как сравнить на своих файлах без самообмана
Возьмите несколько характерных исходников: фотографию, интерфейс с мелким текстом, графику с прозрачностью и изображение с двумя цветами. Для каждого зафиксируйте размеры в пикселях, глубину цвета и одинаковое отношение к метаданным: в противном случае вы сравните ещё и EXIF/ICC, а не только способы сжатия.
Сначала сравните PNG и WebP lossless при одинаковых 8-битных пикселях и проверьте результат декодирования; если важны невидимые цвета полностью прозрачных областей, включите точное сохранение RGBA. Затем отдельно подбирайте JPEG и WebP lossy под приемлемое визуальное качество, глядя в масштабе 100% на лица, текст, тонкие контуры и градиенты. Параметр quality=80 у разных кодировщиков не означает одинаковую величину искажения.
Итог прост: формат выбирают под тип данных и допустимую потерю информации. Двухцветной схеме помогает малая глубина и повторяемость; шумная серая фотография ведёт себя иначе. PNG обеспечивает точные пиксели, но цветная фотография за это часто платит размером. WebP даёт оба режима и потому требует явно указывать, какой из них использован. А JPG и JPEG — просто два имени одного привычного варианта файла.
Первоисточники
Google: частые вопросы о WebP, включая Y′CbCr 4:2:0, глубину каналов и настройку exact.