← На главную

JPEG живёт 30 лет, давя цвет и рябь, невидимые глазу

27.07.2026 15:11 · hackernews

JPEG появился ещё в 1992 году и спокойно пережил несколько технологических «вечностей» — всё благодаря хитрой работе с тем, что наш глаз попросту игнорирует. В основе сжатия с потерями лежат два психофизиологических принципа. Первый: перепады яркости для нас намного важнее перепадов цвета. На сетчатке около 120 миллионов яркостных палочек и лишь около 6 миллионов цветовых колбочек. Второй: низкочастотные изменения — вроде контуров объектов — глаз схватывает отлично, а высокая частота, будь то рябь или текстура кирпича, воспринимается хуже. Примерно так работает камуфляж: высокочастотный шум сбивает низкочастотные границы фигуры.

Кодирование начинается с перевода картинки из привычного RGB в цветовое пространство YCbCr. Так яркость собирается в канал Y, а вся цветовая информация разводится по двум каналам — Cb и Cr. Первое же действие — цвет безжалостно прореживают: яркостный канал оставляют как есть, а Cb и Cr сжимают вдвое или вчетверо (в демонстрации для наглядности брали четверть). Исходные три полновесных канала превращаются в полтора — треть данных уже выброшена.

Дальше каждый канал нарезают на блоки 8×8 и с помощью двумерного дискретного косинусного преобразования (DCT) перегоняют из пространственной области в частотную. Теперь левый верхний угол блока отвечает за самую низкую частоту, а правый нижний — за высокую. На частотной визуализации небо выглядит почти пустым, а шумная кирпичная кладка — серой и густо заполненной.

Следующий шаг — квантование, та самая ручка качества. Есть две таблицы 8×8 с целыми числами: одна для яркости, другая для цвета. Каждый частотный коэффициент делят на соответствующее число из таблицы и округляют, отбрасывая всё дробное. Чем крупнее делитель, тем безжалостнее выбрасывается информация. Таблицы устроены так, что в высокочастотных углах числа больше, а в цветовой таблице числа крупнее, чем в яркостной, — ровно по тем двум принципам восприятия. Ползунок качества просто масштабирует эти числа.

На первый взгляд, после квантования у нас всё ещё столько же чисел, сколько пикселей, но данные стали куда «тише»: появились вереницы нулей и повторяющихся значений. Теперь в дело вступает lossless-сжатие. Блок обходят зигзагом от низких частот к высоким — так все нули группируются в длинные хвосты, и стандартные алгоритмы вроде кодирования длин серий сжимают это до минимального объёма.

Декодирование идёт ровно задом наперёд. Сперва распаковывают lossless-ступень, получая ровно те же квантованные числа. Затем умножают их на коэффициенты из таблиц квантования — частоты восстанавливаются, но округления дают о себе знать: точность утеряна безвозвратно. Обратным DCT блоки возвращаются в пространственную форму. Урезанные ранее цветовые каналы масштабируют до исходных размеров интерполяцией (получается либо мыльно, либо с лесенкой), после чего изображение переводят из YCbCr обратно в RGB, чтобы его смог показать экран. Чем ниже было выставлено качество, тем заметнее артефакты: на разностной картинке расхождения проступают тёмными пятнами именно там, где глазу больше всего не хватило выброшенных деталей.

Читать оригинал →