← На главную

Картинка в QR-коде: красота требует запаса прочности

08.08.2026 23:05 · hackernews

QR-код — это сетка квадратов, которая делится на function patterns и data modules. Function patterns помогают смартфону найти код, поэтому они должны быть чёткими. Data modules хранят данные, и их можно менять без особого вреда для считываемости. Один из трюков — уменьшить data modules: сканер ориентируется на центры пикселей, которые задают finder patterns, так что остальное пространство можно отдать под картинку. В примере из Mastodon Дэйв делит каждый пиксель на сетку 3×3: центральную ячейку занимает бит данных, а остальные восемь — фото. Получается низкодетальное чёрно-белое изображение с шумом «соль и перец».

Если просто резать картинку порогом, полутона пропадут. Bayer filter даёт шахматный узор, но лучше работает Floyd-Steinberg dithering. Идёшь от левого верхнего угла, порогово квантуешь каждый пиксель, а ошибку размазываешь по соседним ещё не обработанным пикселям. Например, вместо 70% яркости ставишь белый — лишние 30% «уходят» в другие пиксели, делая их чуть темнее. В итоге средняя яркость каждого участка ближе к оригиналу, а узор получается менее регулярным и раздражающим.

У такого подхода есть бонус: нерегулярный шум от data modules становится менее заметным. Но он всё равно остаётся: в изображении 147×147, где один из девяти пикселей — случайный цвет QR-кода, это видно. Решение — два прохода error diffusion. Второй обычный, а первый специально маскирует data modules. Их цвет заранее известен, поэтому можно покрасить каждый модуль в нужный цвет и размазать ошибку по восьми соседним пикселям. Ошибка иногда огромная — до 95%, если в тёмной области приходится ставить чисто белый пиксель. Звучит страшно, но именно диффузия не даёт этому превратиться в грязь. Картинка становится заметно чище.

Генератор умеет и другие трюки: поворачивать QR-код перед вставкой картинки и подбирать альтернативные кодировки. Ещё можно позволить генератору перевернуть несколько data modules — внутри QR-кода достаточно error correction, чтобы пара изменённых пикселей не сломала скан. Так работают QR-коды с логотипом в центре. Правда, если ошибка от data modules уже размазана, это почти не улучшает картинку, зато заметно бьёт по считываемости.

Всё это хорошо работает, когда не перебарщивать: большой экран или плакат переживут красивые QR-коды. Бумажный флаер, который могут помять, требует запаса прочности. Это вечный компромисс между эстетикой и надёжностью. И то, что код читается с твоего ноутбука, не значит, что он прочитается с чужого телефона по распечатке в плохом свете. Инструмент выдаёт крошечные картинки без полей, а поле для QR-кода обязательно. Оно должно быть противоположным по цвету центрам больших finder patterns: обычно белым, но для инвертированных кодов — чёрным. Браузеры при увеличении размывают картинку, если не отключить это через CSS.

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