В Google мы постоянно ищем способы ускорить загрузку веб-страниц. Один из способов сделать это — уменьшить размер веб-изображений. Изображения занимают до 60–65 % байтов на большинстве веб-страниц, и размер страницы является основным фактором общего времени рендеринга. Размер страницы особенно важен для мобильных устройств, где изображения меньшего размера экономят как полосу пропускания, так и время автономной работы.
WebP — это новый формат изображений, разработанный Google и поддерживаемый в Chrome, Opera и Android, который оптимизирован для обеспечения более быстрого и меньшего размера изображений в Интернете. Изображения WebP примерно на 30 % меньше по размеру по сравнению с изображениями PNG и JPEG при эквивалентном визуальном качестве. Кроме того, формат изображений WebP имеет те же функции, что и другие форматы. Он поддерживает:
Сжатие с потерями: Сжатие с потерями основано на кодировании ключевых кадров VP8 . VP8 — это формат сжатия видео, созданный компанией On2 Technologies в качестве преемника форматов VP6 и VP7.
Сжатие без потерь. Формат сжатия без потерь разработан командой WebP.
Прозрачность: 8-битный альфа-канал полезен для графических изображений. Альфа-канал можно использовать вместе с RGB с потерями — функция, которая в настоящее время недоступна ни в одном другом формате.
Анимация: поддерживает анимированные изображения в настоящих цветах.
Метаданные: могут содержать метаданные EXIF и XMP (например, используемые камерами).
Цветовой профиль: может иметь встроенный профиль ICC.
Благодаря лучшему сжатию изображений и поддержке всех этих функций WebP может стать отличной заменой большинству форматов изображений: PNG, JPEG или GIF. Более того, знаете ли вы, что WebP предоставляет новые возможности оптимизации изображений, такие как поддержка изображений с потерями и прозрачностью? Ага! WebP — это швейцарский армейский нож среди форматов изображений.
Итак, как же делается это волшебство? Давайте засучим рукава и заглянем под капот.
WebP с потерями
Сжатие с потерями в WebP использует ту же методологию, что и VP8, для прогнозирования (видео) кадров. VP8 основан на блочном предсказании и, как и любой блочный кодек, VP8 делит кадр на более мелкие сегменты, называемые макроблоками.
Внутри каждого макроблока кодер может прогнозировать избыточную информацию о движении и цвете на основе ранее обработанных блоков. Кадр изображения является «ключевым» в том смысле, что он использует только уже декодированные пиксели в непосредственной пространственной окрестности каждого из макроблоков и пытается заполнить неизвестную их часть. Это называется предиктивным кодированием (см. внутрикадровое кодирование видео VP8 ).
Затем избыточные данные можно вычесть из блока, что приводит к более эффективному сжатию. Нам остается лишь небольшая разница, называемая остатком, для передачи в сжатом виде.
После математически обратимого преобразования (знаменитого DCT, что означает дискретное косинусное преобразование) остатки обычно содержат множество нулевых значений, которые можно сжать гораздо эффективнее. Затем результат квантовается и энтропийно кодируется. Забавно, что шаг квантования — единственный, на котором биты отбрасываются с потерями (найдите деление на QPj на диаграмме ниже). Все остальные шаги обратимы и без потерь!
На следующей диаграмме показаны этапы сжатия с потерями WebP. Отличительные особенности по сравнению с JPEG обведены красным.
WebP использует квантование блоков и адаптивно распределяет биты по различным сегментам изображения: меньшее количество битов для сегментов с низкой энтропией и большее количество битов для сегментов с более высокой энтропией. WebP использует арифметическое энтропийное кодирование , обеспечивая лучшее сжатие по сравнению с кодировкой Хаффмана , используемой в JPEG.
Режимы внутреннего прогнозирования VP8
Режимы внутреннего прогнозирования VP8 используются с тремя типами макроблоков:
- яркость 4x4
- яркость 16x16
- цветность 8x8
Эти макроблоки разделяют четыре общих режима внутреннего прогнозирования:
H_PRED (горизонтальное прогнозирование). Заполняет каждый столбец блока копией левого столбца L.
V_PRED (вертикальное предсказание). Заполняет каждую строку блока копией вышеуказанной строки A.
DC_PRED (прогнозирование DC). Заполняет блок одним значением, используя среднее значение пикселей в строке над A и столбце слева от L.
TM_PRED (предсказание TrueMotion). Режим, получивший свое название от метода сжатия , разработанного On2 Technologies . Помимо строки A и столбца L, TM_PRED использует пиксель P выше и слева от блока. Горизонтальные различия между пикселями в A (начиная с P) распространяются с использованием пикселей из L для начала каждой строки.
На диаграмме ниже показаны различные режимы прогнозирования, используемые при сжатии с потерями WebP.
Для блоков яркости 4x4 существует шесть дополнительных внутренних режимов, аналогичных V_PRED и H_PRED, но соответствующих прогнозированию пикселей в разных направлениях. Более подробную информацию об этих режимах можно найти в VP8 Bitstream Guide .
Адаптивное блочное квантование
Чтобы улучшить качество изображения, оно сегментируется на области, имеющие внешне схожие характеристики. Для каждого из этих сегментов параметры сжатия (шаги квантования, мощность фильтрации и т. д.) настраиваются независимо. Это обеспечивает эффективное сжатие за счет перераспределения битов туда, где они наиболее полезны. VP8 допускает максимум четыре сегмента (ограничение битового потока VP8).
Почему WebP (с потерями) лучше, чем JPEG
Кодирование с прогнозированием — основная причина, по которой WebP выигрывает у JPEG. Блочное адаптивное квантование также имеет большое значение. Фильтрация помогает на средних/низких битрейтах. Кодирование булевой арифметики обеспечивает прирост сжатия на 5–10% по сравнению с кодированием Хаффмана.
WebP без потерь
Кодирование без потерь WebP основано на преобразовании изображения с использованием нескольких различных методов. Затем выполняется энтропийное кодирование параметров преобразования и данных преобразованного изображения. Преобразования, применяемые к изображению, включают пространственное предсказание пикселей, преобразование цветового пространства, использование локально возникающих палитр, упаковку нескольких пикселей в один пиксель и замену альфа-канала. Для энтропийного кодирования мы используем вариант кодирования LZ77-Хаффмана, который использует 2D-кодирование значений расстояний и компактных разреженных значений.
Предикторное (пространственное) преобразование
Пространственное прогнозирование используется для уменьшения энтропии за счет использования того факта, что соседние пиксели часто коррелируют. При преобразовании предиктора текущее значение пикселя прогнозируется на основе пикселей, которые уже декодированы (в порядке строк сканирования), и кодируется только остаточное значение (фактическое - прогнозируемое). Режим прогнозирования определяет тип используемого прогноза. Изображение разделено на несколько квадратных областей, и все пиксели в одном квадрате используют один и тот же режим прогнозирования.
Существует 13 различных возможных режимов прогнозирования. Преобладающими являются левый, верхний, верхний левый и верхний правый пиксели. Остальные представляют собой комбинации (средние значения) левого, верхнего, верхнего левого и верхнего правого.
Цвет (декорреляция) Преобразование
Целью преобразования цвета является декорреляция значений R, G и B каждого пикселя. Преобразование цвета сохраняет значение зеленого (G) как есть, преобразует красный (R) на основе зеленого и преобразует синий (B) на основе зеленого, а затем на основе красного.
Как и в случае с предикторным преобразованием, сначала изображение делится на блоки, и один и тот же режим преобразования используется для всех пикселей в блоке. Для каждого блока существует три типа элементов преобразования цвета: green_to_red, green_to_blue и red_to_blue.
Вычесть зеленое преобразование
«Преобразование вычитания зеленого» вычитает значения зеленого из значений красного и синего каждого пикселя. Когда это преобразование присутствует, декодеру необходимо добавить зеленое значение как к красному, так и к синему. Это частный случай общего преобразования цветовой декорреляции, описанный выше, достаточно частый, чтобы гарантировать отсечение.
Индексация цвета (палитры) Преобразование
Если уникальных значений пикселей не так много, может оказаться более эффективным создать массив индексов цвета и заменить значения пикселей индексами массива. Это достигается с помощью преобразования индексации цвета. Преобразование индексации цвета проверяет количество уникальных значений ARGB в изображении. Если это число ниже порогового значения (256), создается массив этих значений ARGB, который затем используется для замены значений пикселей соответствующим индексом.
Кодирование цветового кэша
Сжатие WebP без потерь использует уже просмотренные фрагменты изображения для восстановления новых пикселей. Он также может использовать локальную палитру, если не найдено интересное совпадение. Эта палитра постоянно обновляется для повторного использования последних цветов. На рисунке ниже вы можете видеть, как локальный кэш цветов в действии постепенно обновляется 32 недавно использованными цветами по мере движения вниз.
LZ77 Обратная ссылка
Обратные ссылки представляют собой кортежи кода длины и расстояния. Длина указывает, сколько пикселей в построчном порядке необходимо скопировать. Код расстояния — это число, указывающее положение ранее увиденного пикселя, из которого эти пиксели должны быть скопированы. Значения длины и расстояния сохраняются с использованием префиксного кодирования LZ77.
Префиксное кодирование LZ77 делит большие целые значения на две части: префиксный код и дополнительные биты. Префиксный код хранится с использованием энтропийного кода, а дополнительные биты сохраняются как есть (без энтропийного кода).
На диаграмме ниже показан LZ77 (2D-вариант) с сопоставлением слов (вместо пикселей).
WebP с потерями с альфа-версией
В дополнение к WebP с потерями (цвета RGB) и WebP без потерь (RGB без потерь с альфа-каналом), существует еще один режим WebP, который позволяет кодировать с потерями для каналов RGB и кодировать без потерь для альфа-канала. Такая возможность (RGB с потерями и альфа без потерь) сегодня недоступна ни в одном из существующих форматов изображений. Сегодня веб-мастера, которым нужна прозрачность, вынуждены кодировать изображения в PNG без потерь, что приводит к значительному увеличению размера. WebP Alpha кодирует изображения с низким числом битов на пиксель и обеспечивает эффективный способ уменьшения размера таких изображений. Сжатие альфа-канала без потерь добавляет всего 22% байт по сравнению с кодированием WebP с потерями (качество 90).
В целом, замена прозрачного PNG на WebP с потерями+альфа дает в среднем 60-70% экономии размера. Это было подтверждено как отличная привлекательная функция для мобильных сайтов с большим количеством значков (например, Everything.me ).