Сжать WebP без потери качества
Обновлено
Да, у большинства файлов WebP ещё есть запас. Мы сохранили три изображения во всех типичных настройках качества и сжали их заново. Ниже точные цифры: сколько ушло и насколько сдвинулись пиксели.
Короткий ответ
Файл не становится готовым только потому, что он в WebP. В наших замерах фотография, сохранённая с качеством 90, потеряла ещё 46% веса, скриншот интерфейса 47%, а нарисованная иллюстрация 36%. Средняя разница пикселя при этом около 1.5 из 255 уровней яркости: заметить такое при обычном размере невозможно.
Чем ниже качество при сохранении, тем меньше остаётся запаса: на качестве 80 мы получили от 19 до 35%, а на 75, которое стоит по умолчанию в стандартном консольном кодировщике, всего от 7 до 18%. Обратный случай, WebP без потерь, отдаёт от 60 до 94%.
Что именно мы измерили
Мы взяли три изображения под типичные задачи: фотографию 1980 на 1440, скриншот веб-страницы 1270 на 760 с мелким текстом и нарисованную иллюстрацию 1536 на 1024. Каждое сохранили в WebP с качеством 90, 85, 80 и 75, а также в режиме без потерь: именно это выдают дизайнерские программы и пресеты экспорта. Затем каждый файл прошёл через наш компрессор, а результат сравнили с входом попиксельно.
Фотография, качество 90: 347 178 байт превратились в 187 918, экономия 46%, средняя разница пикселя 1.54, максимальная 27 уровней. На качестве 85: с 207 268 до 131 730 байт, экономия 36%. На качестве 80: с 144 310 до 94 138 байт, 35%. На качестве 75: с 109 010 до 89 690 байт, 18%.
Скриншот, качество 90: 111 870 байт превратились в 59 308, экономия 47%, средняя разница 1.45. На качестве 80 экономия 19%, на 75 около 7%. Иллюстрация, качество 90: 186 080 байт стали 119 092, экономия 36%; на качестве 80 остаётся 19%, на 75 около 7%.
Во всех этих прогонах 99% пикселей изменились не больше чем на 15 уровней яркости из 255. Формат тоже не менялся: WebP возвращается как WebP, в тех же пиксельных размерах.
Почему у сохранённого WebP остаётся запас
Пресет экспорта выбирают один раз и применяют ко всему подряд. Качество, которое действительно нужно портрету с плавными переходами кожи, избыточно для скриншота с плоскими цветами интерфейса, но экспортёр этой разницы не видит. У него к тому же нет времени перебирать варианты: он работает внутри сборки или дизайнерской программы, где всё должно происходить мгновенно.
Есть и вторая причина, и на фотографиях она главная: мелкий сенсорный шум. Зерно, которого не видно при обычном размере, дорого кодировать, потому что для кодека это детали, на которые нужно тратить биты. Именно на его удалении набирается основная экономия, поэтому сжатая фотография под сильным увеличением иногда выглядит даже чище исходного файла.
Наш подход в том, чтобы перебрать несколько кодировок для каждого изображения, а не доверять одной настройке, и затем сверить победителя со входом попиксельно. Если разница могла бы стать заметной, остаётся более безопасный вариант.
Больше всего даёт WebP без потерь
WebP без потерь сохраняет каждый пиксель в точности и платит за это весом. Та же фотография без потерь весила 2 713 020 байт, а после сжатия 174 470 байт: на 94% меньше. Иллюстрация ушла с 1 131 102 до 124 014 байт, на 89% меньше. Скриншот с 152 662 до 60 936 байт, на 60% меньше.
Именно здесь нужна оговорка. На скриншоте, где полно мелкого текста, максимальная разница одного пикселя составила 75 уровней из 255, на краю буквы, хотя 99% пикселей сдвинулись не больше чем на 15. Для баннера или фотографии товара это не имеет значения. Но если файл служит исходником для правок или архивным скриншотом, где важен каждый пиксель, оставьте копию без потерь, а публикуйте сжатую.
Сжимайте один раз, а не три
Каждый проход сравнивает результат с тем, что вы подали на вход, а не со снимком, который сделала камера. Если гонять один и тот же файл по кругу, точка отсчёта уезжает вместе с ним. Мы измерили и это: на первом проходе фотография потеряла 46% веса при средней разнице 1.54 от исходного экспорта и худшем пикселе в 27 уровней. Второй проход дал 135 120 байт, а разница с экспортом выросла до 2.12 в среднем и 41 в худшем случае. Третий проход дал 115 846 байт, 2.44 и 51 соответственно.
То есть файл действительно продолжает худеть, но и повреждения продолжают накапливаться. Сжимайте лучшую копию, которая у вас есть, один раз, а исходник сохраняйте отдельно.
Когда WebP не станет меньше
Некоторые файлы уже на пределе: сильно сжатые миниатюры, изображения после агрессивной сборки, совсем мелкая графика, где вес складывается больше из структуры файла, чем из картинки. Если обогнать вход без перехода визуальной границы нельзя, вы получаете свои исходные байты обратно, а не файл того же размера и чуть хуже.
Анимированный WebP это отдельный случай. Здесь он не сжимается и возвращается без изменений.
Как это сделать
Перетащите файлы на страницу WebP по ссылке ниже. До 20 файлов за раз, до 25 МБ каждый, без регистрации и водяных знаков. Каждый файл обрабатывается в памяти, не пишется на диск и не попадает в логи, а сжатая копия сразу возвращается в браузер.
Если это нужно внутри сборки, у того же движка есть бесплатный API: один запрос отправляет изображение, а в ответе приходит сжатый файл. На бесплатном тарифе 100 изображений в сутки.