Глубокие погружения

Тайная жизнь JPEG: как формат 1992 года захватил интернет

koboshiCo-founder
·10 мин чтения
Тайная жизнь JPEG: как формат 1992 года захватил интернет
Кратко

JPEG не работает по волшебству: за ним стоит конвейер дискретно-косинусных преобразований, таблиц квантования и субдискретизации цветности, который выбрасывает то, что глаз почти не замечает. Спустя тридцать три года он остаётся главным не потому, что лучший, а потому что его открывают везде.

Любой файл .jpg начинается одинаково. Откройте его в hex-редакторе. Первые два байта:

FF D8

Это маркер начала изображения (Start of Image). Без FF D8 декодер не считает файл JPEG. Дальше идут метаданные: версия JPEG, цветовое пространство, смещение до пиксельных данных. Формату больше тридцати лет, он старше современного веб-браузера, но по данным Web Almanac 2025 по-прежнему составляет около 57% всех изображений в интернете.

Кризис хранения, который породил JPEG

В 1986 году серая картинка 640 × 480 занимала 307 КБ. Цветная того же разрешения требовала 921 КБ. Тогда 20-МБ жёсткий диск стоил сотни долларов, а стандартом обмена были дискеты на 1,44 МБ. Одна несжатая фотография могла занять две трети такой дискеты.

Проблема была понятна: нужен единый формат сжатия для фотографий с плавными тонами, а не для векторной графики. Над ней работали несколько групп. Joint Photographic Experts Group, созданный в 1986 году ISO/IEC и ITU-T, собрал лучшие идеи в один черновик. После шести лет доработки стандарт вышел в 1992 году как ISO/IEC 10918-1.

JPEG не замышлялся единственным форматом картинок. Он решал одну задачу: делать фотографии достаточно маленькими, чтобы их можно было хранить и передавать. Это достигается за счёт отбрасывания информации по чётким правилам.

Почему JPEG так хорошо сжимает

JPEG сжимает не одним алгоритмом, а цепочкой шагов. На каждом из них выбрасывается то, что человеческое зрение замечает хуже всего.

1. Преобразование цветового пространства (RGB → YCbCr)

Экран показывает RGB. JPEG внутри себя хранит YCbCr. Канал Y несёт яркость (luminance). Каналы Cb и Cr несут цветность (chrominance, разность синего и разность красного). Дело в том, что в сетчатке около 2,5 миллиона колбочек реагируют на яркость, и только примерно 100 000 — на цвет. Поэтому детали яркости мы видим гораздо чётче, чем цветовые.

2. Субдискретизация цветности (Chroma Subsampling)

Большинство JPEG используют субдискретизацию 4:2:0. На каждые 4 выборки яркости приходится по 1 выборке Cb и 1 выборке Cr. Цветностные каналы хранятся в четверть разрешения канала яркости. Для изображения 4000 × 3000 плоскость Y остаётся 4000 × 3000, а плоскости Cb и Cr сжимаются до 2000 × 1500 каждая. Данные уменьшаются примерно вдвое ещё до настоящего сжатия, и большинство зрителей этого не замечает.

3. Дискретное косинусное преобразование (DCT)

Изображение режется на блоки 8 × 8 пикселей. Каждый блок пропускается через DCT, которое переводит пространственные значения пикселей в частотные. На выходе получается матрица коэффициентов 8 × 8. Значение в левом верхнем углу — DC-коэффициент, средняя яркость блока. Остальные 63 — AC-коэффициенты, отвечающие за детали с ростом частоты.

Высокочастотные коэффициенты отвечают за мелкую текстуру: волосы, траву, шум. Низкочастотные — за крупные формы: небо, стены, тон кожи.

4. Квантование

Здесь происходит потеря информации. JPEG применяет к каждому DCT-блоку таблицу квантования. Это вторая матрица 8 × 8 с делителями. Каждый DCT-коэффициент делится на соответствующий квантователь и округляется.

Стандартная таблица бьёт по высоким частотам сильнее всего:

16  11  10  16  24  40  51  61
12  12  14  19  26  58  60  55
14  13  16  24  40  57  69  56
14  17  22  29  51  87  80  62
18  22  37  56  68 109 103  77
24  35  55  64  81 104 113  92
49  64  78  87 103 121 120 101
72  92  95  98 112 100 103  99

Высокочастотный коэффициент, скажем, 7 делится на 121 и округляется до 0. Он пропадает безвозвратно. Декодер его не увидит. Это и есть сжатие с потерями (lossy): данные уничтожаются, а не просто перекодируются.

При качестве 90 квантователи делятся на меньший масштабирующий коэффициент. При качестве 50 коэффициент выше, больше значений обнуляется, файл становится меньше, а картинка мягче.

5. Энтропийное кодирование (Entropy Coding)

После квантования оставшиеся коэффициенты сканируются зигзагом, кодируются по длине серии (RLE) и сжимаются кодом Хаффмана. Этот этап уже без потерь (lossless). Он только плотнее упаковывает то, что осталось.

Результат: несжатое RGB-изображение 12 МП занимает 36 МБ. Сохранённое как JPEG качества 90 с субдискретизацией 4:2:0 ужимается примерно до 3,5 МБ. Это сжатие примерно в десять раз, а видимые потери заметны только при увеличении.

Насколько это сжатие с потерями на самом деле?

Ущерб распределяется неравномерно.

КачествоТипичный размер (12 МП)Визуальное воздействие
95+~8 МБПочти незаметно; предпочтительно для архивирования
90~3,5 МБНезначительное смягчение; стандарт для камер
75~1,8 МБЗаметное размытие мелких деталей; веб-стандарт
50~1,0 МББлочные артефакты очевидны при масштабе 100%
30~600 КБЦветовой бандинг, шум москитов, непригодно для печати

С падением качества проявляются три типа артефактов. Появляется блочность, то есть видимые границы сетки 8 × 8, особенно в плавных градиентах вроде неба. Звон (ringing) — осциллирующие ореолы вокруг контрастных границ, например текста на фоне. Цветовое размытие возникает, когда субдискретизация цветности размазывает цвет через резкие границы.

Хуже всего проявляет себя потеря поколения (generation loss). Откройте JPEG, отредактируйте, сохраните снова как JPEG. Каждое сохранение перезапускает весь конвейер: RGB → YCbCr → субдискретизация → DCT → квантование. Ошибки округления накапливаются. Через 10 поколений изображение может выглядеть так, будто нарисовано акварелью. Через 50 — оно неузнаваемо.

Зелёный сдвиг и другие особенности пересжатия

Если много раз пересохранять JPEG, цветовая температура может поползти. Некоторые картинки приобретают едва заметный зелёный оттенок. Другие сдвигаются в пурпурный. Причина кроется в цветностных каналах.

JPEG хранит Cb и Cr в пониженном разрешении и агрессивно квантует их. Каждое сохранение вносит ошибку округления в оба канала. Обратное преобразование в RGB делается по формулам:

R = Y + 1.402 × (Cr - 128)
G = Y - 0.344136 × (Cb - 128) - 0.714136 × (Cr - 128)
B = Y + 1.772 × (Cb - 128)

Зелёный вычисляется и из Cb, и из Cr. Когда повторное квантование сдвигает Cb вверх и Cr вниз хотя бы на один шаг квантования, канал G уходит. Положительное смещение в Cb толкает зелёный вниз. Отрицательное смещение в Cr толкает зелёный вверх. Взаимодействие несимметрично, потому что коэффициенты -0.344136 и -0.714136 имеют разную величину. В итоге зелёный медленно накапливается в некоторых областях изображения, особенно там, где исходные значения цветности уже были близки к границам квантования.

Это не гарантированный эффект. Он зависит от таблиц квантования кодировщика, режима субдискретизации и содержимого изображения. Но он реален, воспроизводим, и это одна из причин, по которой профессиональные рабочие процессы избегают пересохранения JPEG.

Если JPEG такой неидеальный, почему его использует всё?

JPEG популярен не потому, что идеален. Он популярен, потому что достаточно хорош и везде работает.

Базовый патент JPEG, который принадлежал Forgent Networks, истёк в 2006 году. Формат свободен от роялти. Аппаратные и программные декодеры есть в камерах, телефонах, принтерах и браузерах, поэтому отрисовка почти ничего не стоит. Для социальных сетей, новостных сайтов и почтовых вложений JPEG качества 75 на экране телефона почти не отличить от оригинала. К тому же вся инфраструктура — CMS, CDN, библиотеки изображений, архивы — говорит на JPEG. Заменить формат недостаточно: нужна ещё и причина переносить петабайты уже существующих файлов.

Форматы, которые должны были победить

JPEG пытались заменить несколько раз. Пока ни один формат не занял его место полностью.

ФорматLossyLosslessПрозрачностьАнимацияМакс. битовая глубинаКлючевое преимущество
JPEGДаНетНетНет8-bitУниверсальная поддержка
PNGНетДаДаНет16-bitИдеальное lossless, альфа-канал
WebPДаДаДаДа8-bitНа 25–35% меньше JPEG, нативно в браузере
HEICДаДаДаДа16-bit~50% меньше JPEG, стандарт Apple
AVIFДаДаДаДа12-bitЛучшее сжатие сегодня, свободно от роялти
JPEG XLДаДаДаДа32-bitLossless пересжатие JPEG, прогрессивный decode

PNG закрыл проблему lossless, но для фотографий его файлы в 5–10 раз больше JPEG. Он занял нишу скриншотов, UI-ассетов и графики.

WebP, выпущенный Google в 2010 году, обычно даёт файлы меньше JPEG и добавляет прозрачность и анимацию. Сейчас он поддерживается всеми крупными браузерами. Web Almanac 2025 оценивает долю WebP среди LCP-изображений в 11% против 7% в 2024. Это безопасный вариант для апгрейда сегодня.

HEIC от Apple (2017) использует сжатие HEVC внутри контейнера ISOBMFF. Он даёт файлы примерно на 40–50% меньше JPEG и может хранить несколько изображений в одном файле. В экосистеме Apple HEIC доминирует, но в остальном мире застопорился из-за патентных пулов HEVC.

AVIF от Alliance for Open Media (2019) происходит из видеокодека AV1. По коэффициентам сжатия он лидирует среди широко поддерживаемых форматов: при том же качестве примерно на 30% меньше WebP. Минус — скорость декодирования. AVIF на мобильных устройствах может рендериться в 2–3 раза дольше JPEG, тратя батарею и задерживая Largest Contentful Paint.

JPEG XL (ISO/IEC 18181, 2021) технически превосходит всех перечисленных. Сжимает на 50–60% меньше JPEG, декодируется быстро, поддерживает прогрессивное декодирование (пригодная картинка уже после загрузки лишь ~1% файла). Главное — умеет без потерь пересжимать существующие JPEG, экономя около 20% размера с побитовым восстановлением оригинала. Другие форматы так не умеют.

Где мы сейчас

У JPEG XL была трудная юность. Google добавил экспериментальную поддержку в Chrome в 2021 году, а затем убрал её 31 октября 2022 года. Это прозвали «решением на Хэллоуин». Заявленная причина: недостаточный инкрементальный выигрыш над существующими форматами. Реакция последовала мгновенно: issue в Chromium стал вторым по количеству звёзд в истории проекта. Google обвинили в защите AVIF, формата, привязанного к Alliance for Open Media, которую Google соосновал.

В конце 2025 года Chromium развернул курс. Новый декодер на Rust (jxl-rs) попал в Chrome Canary. Chrome 145, выпущенный в феврале 2026 года, поставил поддержку JPEG XL за флагом. Safari поддерживает формат с 2023 года, Firefox Nightly интегрирует тот же Rust-декодер. JPEG XL пока не включён по умолчанию, но он вернулся в кодовую базу.

AVIF в 2026 году выглядит как прагматичный выбор. Поддержка в браузерах широкая, кодировщики улучшаются. Cloudinary и Cloudflare автоматически отдают AVIF при согласовании заголовка Accept. По данным CoreDash, медианная страница с AVIF или WebP показывает 81% хороших показателей LCP против 64% для страниц только с JPEG.

Что из этого следует

JPEG — компромисс тридцатилетней давности. Он жертвует цветовым разрешением, высокочастотной текстурой и числовой точностью ради размеров файлов, которые сделали цифровую фотографию возможной в 1990-х. Артефакты хорошо изучены. Потеря поколения реальна. Зелёный сдвиг случается.

Тем не менее JPEG держится по той же причине, что и раскладка QWERTY: переучиваться дороже, чем мириться с неудобствами.

Что делать на практике:

Храните мастеры в высоком качестве. Архивируйте оригиналы как PNG, TIFF или JPEG качества 95+. Никогда не редактируйте повторно из веб-экспорта качества 75.

Отдавайте современные форматы динамически. Используйте CDN или сервис изображений, который по заголовку Accept согласует AVIF, WebP или JPEG XL. Храните один мастер, а edge пусть конвертирует по требованию.

Не перекодируйте JPEG пакетно. Каждое поколение уничтожает данные. Если нужны файлы меньше, перекодируйте из мастера, а не из другого JPEG.

JPEG не исчезнет в одночасье. Он угаснет так же, как GIF: всё ещё открывается везде, всё ещё поддерживается в каждом просмотрщике, но всё чаще уступает форматам, которые делают ту же работу меньшим числом байтов и с меньшим числом артефактов. В этот раз альтернативы выглядят серьёзнее.

Ещё посты в блоге