← Вернуться в блог

Пакетное сжатие прозрачных PNG без порчи краёв логотипа

Только что закончил набор бренд-ассетов для интернет-магазина. Шестнадцать прозрачных PNG — логотипы в трёх размерах, несколько угловых значков, пара дизайнов стикеров. В Figma выглядят идеально. Экспортируешь как PNG с включённой прозрачностью, кидаешь папку на рабочий стол и проверяешь общий размер: 2,4 МБ. На шестнадцать маленьких графики. На мобильном это две секунды загрузки до того как хоть что-то на странице начнётся.

Запускаешь компрессор. Размеры падают драматически — отлично. Но потом загружаешь сжатую версию на страницу магазина и замечаешь что-то не то по краям логотипа: тонкая белая линия где был плавный переход, или зубчатая лесенка вдоль изогнутого края. Это ловушка сжатия прозрачных PNG и почти никто об этом не говорит, потому что большинство инструментов прячет проблему за слишком маленьким превью. Я покажу что именно происходит под капотом, дам реальные цифры и скажу какой подход для какого типа ассета подходит.

Цифры: реальный прозрачный логотип, три пути сжатия

Я специально создал тестовое изображение: композиция 1200×1200 пикселей с центральным бейджем-логотипом, размытым свечением (мягкий альфа) и несколькими жёсткокрайми стикерами в углах. Используется RGBA — четыре канала вместо трёх — каждый пиксель несёт красный, зелёный, синий и непрозрачность. Прогнал через три пути и замерил всё:

МетодРазмерЭкономияМягкий альфа сохранён?
Оригинал (неоптимизированный RGBA)156,6 КБДа — 649 298 частично-альфа-пикселей
Lossless пере-кодирование (только optimize)126,0 КБ−19,6%Да, идентичные пиксели
PNG8 квантование (256 цветов, 1-bit альфа)11,3 КБ−92,8%Нет — ноль частичных альфа-пикселей
Тот же прозрачный логотип до (156,6 КБ с мягким свечением) и после PNG8-сжатия (11,3 КБ с жёстким ореолом по краю). Зум края показывает плавный-жёсткий альфа-переход.
Прозрачный логотип 156,6 КБ сжат до 11,3 КБ через PNG8 — сокращение 92,8%. Левая панель показывает оригинал с его мягким свечением, плавно уходящим в прозрачность. Центральная панель показывает результат PNG8: свечение превратилось в жёсткое кольцо, потому что кодер округлил каждое промежуточное альфа-значение до полностью непрозрачного или полностью прозрачного. Правая панель увеличивает край — виден ступенчатый паттерн где плавный градиент стал бинарным вкл/выкл. Формы с жёсткими краями (бейдж, звезда, угловые стикиеры) выглядят идентично. Страдает только область мягкого свечения.

Что реально делает PNG8 (и почему он портит мягкие края)

PNG8 означает индексированный PNG. Вместо хранения отдельного RGB-значения для каждого пикселя кодер строит палитру — до 256 цветов всего — и каждый пиксель это просто число указывающее на запись палитры. Это радикально меньше, потому что один байт на пиксель заменяет три (или четыре с альфой).

Проблема в том как PNG8 хранит прозрачность. В индексированном PNG каждая запись палитры получает одно значение прозрачности. Большинство кодеров округляет это до полностью прозрачного или полностью непрозрачного — нет места для «37% полупрозрачного». Каждый пиксель который был полупрозрачным (анти-алиасинг края, тени, свечение, затухающие градиенты) прыгает к одному из двух крайних значений.

В моём тестовом изображении у оригинала было 649 298 пикселей с промежуточными значениями альфы — всё мягкое свечение плюс анти-алиасинг вокруг круга и звезды. После конвертации PNG8 через тот же движок что использует наш сайт (upng-js медианная-срез квантизация, округление альфа до 1-bit) это число упало ровно до нуля. Каждый из этих 649 тысяч пикселей стал либо 255 (непрозрачным) либо 0 (прозрачным). Визуально — это ореол что видишь на центральной панели выше: жёсткое кольцо где свечение раньше плавно угасало.

Это имеет значение? Полностью зависит от что внутри твоего прозрачного PNG.

Когда PNG8 совершенно безопасен (используй смело)

Если твоя прозрачная картинка содержит только формы с жёсткими краями — плоские цветные логотипы, плоские иконки, квадратные или скруглённые стикеры, вырезки продуктов сфотографированных на чисто-белом фоне — PNG8 это практически бесплатные деньги. Альфа-канал нечего мягкого испортить, и ты получаешь сокращение размера более 90% при нулевой визуальной разнице.

Когда PNG8 кусается (избегай или обходи)

Если твой ассет попадает в эту категорию, у тебя три варианта:

  1. Сначала сплющай эффект.Объедини слой свечения/тени с сплошным фоновым цветом, затем экспортируй как не-прозрачный PNG или JPEG. Теперь у тебя нет альфа чтобы испортить. Сжимай нормально. Так большинство про-дизайнеров обращаются с финальными продакшн-ассетами.
  2. Используй только lossless-оптимизацию.Пропусти PNG8. Прогони файл через lossless-PNG-оптимайзер (OxiPNG, zopfli) который пере-кодирует deflate-поток эффективнее не трогая значения пикселей. Сэкономишь может 15–25% вместо 93%, но каждый пиксель останется как задумано. Достаточно для hero-изображений и header-логотипов где качество не торгуется.
  3. Принять и проверить в размере отображения.Сожми как PNG8, скачай результат, открой рядом с оригиналом в реальном размере в котором он будет на веб-странице (не увеличено). Если ореол невидим при 1:1, используй. Большинство пользователей видят логотипы 80–200 px ширине где ореол в 2 px ниже порога восприятия. Но не предполагай — проверь.

Батч-воркфлоу: сжать 20 прозрачных PNG за один раз

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

  1. Собери свои прозрачные PNG.Положи все в одну папку. Смесь логотипов, стикеров, вырезок — всё что нужно ужать.
  2. Быстро проверь каждый при 200% зуме.Ищи мягкие края, свечения или затухающие области возле границ форм. Раздели на две стопки: «только жёсткие края» и «есть мягкий альфа».
  3. Закинь весь батч в браузерный компрессор.Инструмент что я использую принимает до 20 файлов одновременно, работает целиком в твоём браузере (ничего не грузится на сервер), авто-детектит формат. Закинь все 20 одним drag-and-drop.
  4. Дай движку запустить PNG8.Для стопки «жёсткие края» дефолтный вывод уже оптимален. Для стопки «мягкий альфа» просмотри каждый результат при 1:1 перед решением оставить или переключиться на lossless-режим.
  5. Скачай батч.Один клик скачивает всё как отдельные файлы. Имена файлов сохраняются. Бросай прямо в CMS или платформенный аплоадер.

Общее время от открытия папки до готовой закачки: около 30 секунд на батч из 20 файлов. Без установки софта. Без создания аккаунта. И критично: твои исходные файлы никогда не покинули устройство — сжатие произошло локально во вкладке браузера.

Ошибки которые съедают часы (я допустил большинство)

Связанные гайды для специфических ситуаций

Твои нужды по прозрачным PNG могут пересекаться с другими задачами по изображениям. Эти гайды глубже покрывают смежные темы:

Итог

Прозрачные PNG раздуты потому что RGBA добавляет четвёртый канал и большинство дизайн-инструментов экспортирует неоптимизированно. PNG8-сжатие (медианная-срез палитрная квантизация с 1-bit альфой) может ужать их более чем на 90% во вкладке браузера без установки ПО. Единственное за чем следить — мягкий альфа: свечение, падающие тени, анти-алиасированный текст — что PNG8 превращает в жёсткие края. Если у твоих ассетов ничего такого нет — сжимай без колебаний. Если есть — сплющай эффект, используй lossless-режим, или проверь в размере отображения что ореол невидим.

Твой логотип заслуживает выглядеть резким на каждом экране. Он также заслуживает загружаться быстро. Обе цели достижимы — просто выбери правильный путь для конкретного ассета что держишь в руках.

Сжми свои прозрачные PNG прямо сейчас

Закинь до 20 прозрачных PNG сразу. Режим PNG8 ужимает жёстко-краевые логотипы на 90%+ с сохранением прозрачности. Предпросмотр перед скачиванием. Бесплатно, работает полностью в браузере, файлы не покидают устройство.

Сжать изображения бесплатно →
Об авторе: Chuan
Независимый разработчик, построивший CompactJPG после наблюдения как дизайнеры мучатся с слишком большими прозрачными PNG (либо превышают лимит загрузки, либо портятся JPEG-конвертерами). Всё работает в браузере потому что твои бренд-ассеты принадлежат твоему устройству, а не чьему-то ещё серверу.