Вслед за материалом о том, почему вашему монитору не под силу отобразить истинный бирюзовый, а 65% цветового спектра остаются для него недосягаемыми, один мой приятель, далекий от мира высоких технологий, задал резонный вопрос: «Если дисплей искажает реальность, то как JPEG распоряжается оставшимися 35% данных?» Вопрос заставил меня углубиться в спецификации. Спустя полчаса я уже не помнил первоначальную цель, захваченный открытием: инженеры, финализировавшие стандарт в 1992 году, фактически совершили реверс-инжиниринг человеческого зрения и интегрировали его механизмы в алгоритм сжатия.
И это не преувеличение. В предыдущей статье я демонстрировал, как экраны эксплуатируют метамерию, подменяя полный спектр тремя стимулами, что мозг воспринимает как чистый цвет. JPEG идет еще дальше. Каждый этап его пайплайна — это выверенный хак, нацеленный на конкретные несовершенства нашей зрительной системы. Пока монитор манипулирует колбочками сетчатки, JPEG обманывает всё остальное: от контрастной чувствительности до механизмов распознавания частот в коре головного мозга.
Я хочу поделиться этим с вами, поскольку это один из самых элегантных примеров инженерной мысли, что я встречал за 12 лет практики. Если раньше мы говорили о том, как мало мы видим, то сейчас разберем, как мало нам достаточно видеть, чтобы мозг поверил в полноту картины. А в конце я проверил теорию на практике.
Глаз — это не видеокамера (очевидный, но важный факт)
Мы привыкли воспринимать глаза как некие биологические сенсоры: свет падает на сетчатку, данные передаются в мозг, и возникает «картинка». Кажется, что это аналог матрицы фотоаппарата. Но это заблуждение.
Ваше зрение — это крайне предвзятый инструмент с массой аппаратных ограничений. Сетчатка снабжена двумя типами фоторецепторов: около 120 миллионов палочек отвечают за восприятие яркости, и лишь 6–7 миллионов колбочек обеспечивают цветовое зрение.
Задумайтесь: соотношение 20 к 1. Фактически ваша сетчатка представляет собой черно-белый сенсор сверхвысокого разрешения, к которому вторым слоем небрежно приклеили низкокачественный цветовой модуль из эпохи ранних веб-камер.
Разработчики JPEG прекрасно это осознавали.
YCbCr: почему JPEG избавляется от RGB в первую очередь
При сохранении изображения в формате JPEG первым делом происходит не сжатие и даже не оптимизация, а смена парадигмы описания цвета.
Исходные данные поступают в RGB. Так их выводит монитор и захватывает камера. Однако JPEG мгновенно транслирует их в систему YCbCr:
-
Y — яркостная составляющая (Luma).
-
Cb — синяя цветоразностная компонента.
-
Cr — красная цветоразностная компонента.
Зачем такие сложности? На первый взгляд, это лишняя вычислительная нагрузка. Ведь RGB универсален. Но в RGB все каналы критически важны: уберите любой из них, и структура изображения рухнет.
В YCbCr ситуация иная. Канал Y несет информацию, которую наш глаз считывает безупречно благодаря 120 миллионам палочек. Мы замечаем малейшие нюансы теней, контуров и текстур. А каналы Cb и Cr обрабатываются всего 6 миллионами колбочек. Цветовое разрешение нашего зрения на порядок грубее яркостного.
Переход к YCbCr — это стратегическое разделение данных на те, что глаз «видит отчетливо», и те, которыми можно безболезненно пожертвовать.
Формула преобразования говорит сама за себя:
Y = 0.299 × R + 0.587 × G + 0.114 × B
Обратите внимание на веса: зеленый составляет более половины значения яркости (0.587), тогда как синий — лишь 0.114. Это математическая модель нашей сетчатки. Пик чувствительности глаза приходится на желто-зеленую область (около 555 нм). Эволюция затачивала зрение приматов под поиск спелых плодов в листве, и стандарт 1992 года филигранно это копирует.
Если вы когда-нибудь переводили фото в ЧБ и замечали, что простое усреднение каналов дает плоскую картинку, а правильные коэффициенты — глубокий контраст, знайте: вы видели работу Y-канала JPEG.
Chroma subsampling — легальный чит-код
После конвертации в YCbCr алгоритм позволяет хранить цветовые каналы с пониженным разрешением. Это называется цветовой субдискретизацией (chroma subsampling), где самым популярным является режим 4:2:0.
Что это означает? Яркость (Y) сохраняется в исходном виде, а для цвета (Cb и Cr) берется один пиксель на блок 2×2 яркостных пикселя.
Мы отбрасываем 75% цветовых данных, и человеческий глаз этого практически не замечает. Почему? Потому что биологическая периферия нашего зрения устроена так же. Пространственное разрешение цветового восприятия в несколько раз ниже яркостного.
JPEG не просто сжимает цвет — он отсекает то, что наш мозг и так не в состоянии обработать.
Проверить это легко: разложите изображение в Photoshop на каналы YCbCr. Цветовые компоненты будут выглядеть как размытые пятна, хотя мозг будет упорно твердить, что фото четкое. Вы просто никогда не видели цвет в отрыве от яркости — ваша визуальная система объединяет их автоматически.

ДКП: эксплуатация нейронов зрительной коры
Цвет урезан, но основное сжатие происходит на этапе дискретного косинусного преобразования (ДКП) и квантования. Казалось бы, причем здесь биология?
Дело в том, что ДКП дробит картинку на блоки 8×8 и раскладывает их на 64 частотных компонента: от плавных градиентов до резких деталей и шумов.
Ниже представлен базис ДКП для такого блока — набор из 64 «элементарных кирпичиков», из которых собирается любое изображение:

Поразительно, но нейроны первичной зрительной коры (зона V1) функционируют по схожему принципу. Еще в 1960-х годах Хьюбел и Визел (лауреаты Нобелевской премии) выяснили, что эти клетки реагируют на полосы определенной ориентации и частоты. Ваша зрительная кора буквально выполняет подобие спектрального анализа входящего сигнала.
Таким образом, ДКП — это математическая аппроксимация того, как мозг декомпозирует визуальный поток.
Квантование — карта ваших когнитивных пробелов
После ДКП мы получаем 64 коэффициента. Чтобы добиться сжатия, их нужно огрубить или обнулить. Для этого используется таблица квантования: каждый коэффициент делится на соответствующее число и округляется.
Вот как выглядит стандартная матрица для яркости:

Принцип прост: левый верхний угол (низкие частоты) содержит малые делители — здесь мы храним данные бережно. Правый нижний угол (высокие частоты) имеет огромные значения — эти детали выбрасываются безжалостно.
Эта матрица — не что иное, как цифровое воплощение графика контрастной чувствительности (CSF) человека.
CSF определяет, насколько хорошо мы видим узоры разной частоты. Пик нашей зоркости находится в диапазоне 3–5 циклов на градус обзора. Слишком плавные или слишком мелкие детали мы распознаем хуже, а за порогом 60 циклов на градус наступает полная визуальная слепота.
Значения в таблице подобраны эмпирически через психовизуальные тесты. Цель — сделать так, чтобы артефакты округления возникали именно там, где глаз не в силах отличить оригинал от аппроксимации.
Понижая параметр Quality в редакторах, вы фактически увеличиваете эти делители, вторгаясь в зону видимых глазом деталей. Quality 100 — это ювелирная точность, Quality 10 — грубая имитация, предполагающая, что зритель почти слеп.
Экспериментальное подтверждение
Теория красива, но можно ли визуализировать то, что JPEG «отрезает» от реальности? И действительно ли это незаметно?
Я воспользовался простым скриптом на Python: берем эталонный PNG, сохраняем его как JPEG с разной степенью сжатия, а затем вычитаем полученный результат из оригинала. То, что останется — и есть выброшенная информация.
from PIL import Image
import numpy as np
original = np.array(Image.open("photo.png")).astype(np.float32)
for q in [95, 80, 50, 20, 5]:
Image.open("photo.png").save(f"q{q}.jpg", quality=q)
compressed = np.array(Image.open(f"q{q}.jpg")).astype(np.float32)
diff = original - compressed
# Визуальная нормализация
diff_visual = ((diff - diff.min()) / (diff.max() - diff.min()) * 255)
Image.fromarray(diff_visual.astype(np.uint8)).save(f"diff_q{q}.png")
Я ожидал увидеть хаотичный цифровой шум, но результат оказался куда интереснее.

Призраки в деталях
При Quality 95 карта различий практически черная. Только при экстремальном выкручивании контраста проявляются едва уловимые следы.
При Quality 80 (золотой стандарт веба) на карте проступают контуры, резкие границы и высокочастотные текстуры: волосы, ворс ткани. Это именно те данные, которые ДКП отправляет в высокочастотный спектр, и которые квантование режет первыми.
При Quality 50 разница напоминает детальную гравюру. Здесь собраны все тонкие линии и микротекстуры.
На Quality 5 ситуация становится драматичной.
Здесь в «мусоре» отчетливо видна вся композиция снимка. Алгоритм стал настолько агрессивным, что начал уничтожать и средние частоты — те самые, к которым наш глаз максимально чувствителен. Именно поэтому такие изображения кажутся нам «разваленными»: кодек перешел черту дозволенного биологией.
По сути, грань между качественным фото и визуальной кашей — это и есть граница вашей контрастной чувствительности. Для большинства сцен она пролегает в диапазоне Quality 20–40.
Магия числа 80
Мне стало любопытно: почему именно 80 считается эталоном для веба?
Я проанализировал зависимость размера файла и индекса структурного сходства (SSIM) от параметра качества.
from PIL import Image
import numpy as np
from skimage.metrics import structural_similarity as ssim
import io
original = np.array(Image.open("photo.png"))
results = []
for q in range(5, 101):
buf = io.BytesIO()
Image.open("photo.png").save(buf, format="JPEG", quality=q)
size_kb = buf.tell() / 1024
buf.seek(0)
compressed = np.array(Image.open(buf))
score = ssim(original, compressed, channel_axis=2)
results.append((q, size_kb, score))

Вес файла растет экспоненциально при приближении к отметке 100. Разница в объеме между Quality 80 и 95 может быть двукратной, при этом SSIM изменится лишь в третьем знаке после запятой.
Quality 80 — это точка перегиба, обусловленная нашей биологией. До этого порога квантование затрагивает лишь то, что мы почти не видим. После — начинает «резать по живому».
Эпилог: инженерия восприятия
Мы привыкли использовать тег <img>, не задумываясь о том, какая колоссальная научная база стоит за привычными форматами. JPEG — это не просто математика, это десятилетия исследований в области психофизики, изучение порогов восприятия и изящная попытка адаптировать данные под конкретный биологический пайплайн.
JPEG — это алгоритм сжатия восприятия, а не просто байтов.
Современные WebP и AVIF продолжают эту традицию. Например, в AVIF внедрен синтез зернистости (film grain synthesis): кодек не хранит шум, а генерирует его на лету, зная, что мозг не помнит точного паттерна зерна, лишь его характер. Снова хак над биологией.
Самое ироничное, что таблицы квантования в спецификации JPEG носят лишь рекомендательный характер. Продвинутые энкодеры вроде MozJPEG тратят ресурсы на подбор индивидуальных матриц для каждого кадра, создавая детальную карту того, что не увидите именно вы в этой конкретной сцене.
А новый стандарт JPEG XL идет еще дальше, интегрируя перцептивную метрику Butteraugli непосредственно в ядро. Кодек моделирует работу вашего зрительного тракта, включая адаптацию к яркости и маскировку контуров, буквально спрашивая систему: «Заметишь ли ты подмену?»
Спустя тридцать лет мы всё так же балансируем на грани между видимым и невидимым, просто инструменты стали острее, а модели — точнее.
Помните об этом, глядя на характерные блоки 8×8 на пережатом фото. Это не просто ошибка — это сетка, по которой алгоритм препарировал реальность, адаптируя её под ваши глаза. Обычно он делает это настолько мастерски, что швы остаются невидимыми.
Примечание для специалистов: я сознаю, что при ярком свете палочки инактивируются, а острота зрения определяется нейронным пулингом. Но метафора разделения на яркостный и цветовой сенсоры слишком точно отражает архитектуру JPEG, чтобы ей пренебрегать.


