Мозаика из пинов по фотографии на PHP

Мозаика из пинов по фотографии на PHP

15 декабря 2025

Фотоконструктор — набор для творчества, который позволяет своими руками по фотографии собрать картину в стиле «пин-арт», формируя изображение на полотне с помощью пинов разного диаметра. Пин — это тонкий заостренный с одной стороны металлический стержень с круглой шляпкой на другой стороне. Конструктор позволяет создавать аватары, персонализированные подарки или открытки из дорогих сердцу фотографий для дорогих сердцу людей.

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

Подготовка изображения

Начнем по порядку. Когда пользователь загружает изображение в фото-конструктор, первое, что нужно проверить, — подходит ли оно для преобразования. Сначала проводятся стандартные валидации: размер (ширина и высота), квадратная ли форма, тип изображения, объем файла. Изображения объемом в гигабайт не подходят! Если проверка пройдена, переходим к следующему шагу — изменению размера изображения под общий стандарт в 600×600 пикселей, чтобы потом основному алгоритму можно было работать с картинкой.

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

  • Адаптивное изменение резкости. Резкость становится более интенсивной на краях и менее интенсивной в центре изображения. Для этой цели применяется функция PHPImagick::adaptiveSharpenImage.
  • Выравнивание гистограммы изображения. Для автоматического выравнивания яркости изображения используется функция PHPImagick::equalizeImage.

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

Адаптивное улучшение резкости

Алгоритм адаптивного улучшения резкости (adaptive sharpening) предназначен для изменения четкости и детализации изображения. Основная идея в том, чтобы добавить резкость только там, где это необходимо, избегая усиления шума и артефактов в менее важных и однородных областях. Ниже сформулированы основные шаги и принципы работы алгоритма.

01 Определение областей для изменений Области для изменений Алгоритм анализирует изображение и определяет, где резкость может быть улучшена. Для этой задачи подходят различные методы, например анализ градиентов или контрастности.
02 Создание маски резкости Маска резкости На основе анализа создается матрица коэффициентов, которая указывает, где и насколько следует усилить резкость. Для однородных областей значения маски низкие. В областях с высоким контрастом или резкими границами — высокие.
03 Применение фильтра Применение фильтра В нашем приложении используется фильтр Гаусса по маске резкости, но можно применять и другие фильтры, которые выделят детали, не испортив изображение.
04 Совмещение с оригиналом Совмещение с оригиналом Новое изображение с улучшенной резкостью комбинируется с исходным для сохранения естественного цвета и текстуры, избегания чрезмерного усиления резкости и появления артефактов.

Выравнивание гистограммы изображения

Алгоритм выравнивания гистограммы (histogram equalization) используется для повышения контрастности изображения. Суть заключается в таком преобразовании яркости пикселей, чтобы результирующая гистограмма распределения яркостей стала максимально равномерной на всем доступном динамическом диапазоне. Основные принципы работы алгоритма.

01 Построение и анализ гистограммы Построение Гистограмма изображения показывает распределение яркости пикселей и отображает количество пикселей для каждого уровня яркости.
02 Выравнивание Выравнивание Метод выравнивания гистограммы преобразует распределение интенсивностей пикселей, приводя результирующую гистограмму к максимально возможному плоскому виду.
03 Улучшение контраста Улучшение контраста Выравнивание гистограммы делает изображение контрастнее, поскольку самые темные и светлые области будут ярче выражены. Улучшение помогает восстановить изображения с низким контрастом, где детали могут быть потеряны.

Визуализатор поделки

Предварительно обработанное изображение передается основному алгоритму, который визуализирует поделку и генерирует схему сборки. Если размер изображения после приведения к стандарту составляет 600×600 пикселей, а количество ячеек в поделке — 60×60, получается, что входное изображение делится на блоки (клетки) размером 10×10 пикселей, а каждому блоку ставится в соответствие свой цвет.

Обходя каждый блок, проходим по каждому пикселю и смотрим, какой у него RGBA-цвет. Для получения составляющих цвета пикселя — красного, зеленого, синего, и альфа-компонента (прозрачности) — используются две функции: imagecolorat и imagecolorsforindex. Соответствующие компоненты цвета для каждого пикселя суммируются и в конце прохода усредняются посредством деления на сто. 100 — количество пикселей в блоке размером 10×10.

Если оказывается, что прозрачных пикселей в блоке больше, чем непрозрачных, функция определения цвета возвращает false. Пропускаем отрисовку для блока с false, — в поделке будет пустая клетка без пина. В противном случае возвращается средний RGBA-цвет заполненной клетки. Затем из палитры подбирается «цвет пина», ближайший к цвету клетки.

Палитра состоит всего из пяти оттенков серого: от черного до белого. Цвета палитры настраиваются перед визуализацией деморисунка, или, если пользователь не скорректировал палитру, используются цвета по умолчанию. Поскольку цвета палитры бывают только серые, а пины рисуем черным, возникает вопрос: как отразить разные цвета палитры на полотне? Очень просто — чем светлее клетка, тем меньше диаметр пина, а чем темнее, тем диаметр больше.

Формула расстояния между цветами
«Расстояние» между различными цветами

Формула для нахождения ближайшего к цвету клетки серого «цвета пина» указана выше. Где d — «расстояние» между цветами; r2, g2, b2 — RGB-компоненты цвета клетки; а r1, g1, b1 — RGB-компоненты цвета палитры. Находим ближайший цвет палитры, для которого расстояние d окажется наименьшим.

Последовательно просматривая каждый блок изображения в цикле, определяем «цвет пина», либо отсутствие пина в клетке. На визуализации полотна рисуем кружок определенного диаметра: чем темнее серый цвет, тем больше диаметр черного круга. Сохраняем диаметр круга в матрицу 60×60 для схемы сборки.

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

Визуализация поделки выполняется библиотекой php-svg в векторном формате с использованием функций: SVGCircle — для рисования пинов, SVGText — для вывода диаметра на пинах и рисования координат, SVGLine — для рисования линий. Векторные изображения четкие и отлично масштабируются.

Оригинал изображения
Сгенерированный демо-рисунок
Оригинальное изображение и визуализация поделки

Схема сборки

Матрица диаметров пинов размером 60×60 была рассчитана на предыдущем этапе. На схеме сборки последовательно располагаются 36 частей, каждая из которых размером 10×10 пинов. Сначала генерируем SVG-картинки частей и добавляем в каждую координатную сетку, чтобы пользователь сориентировался. Затем все части собираем в единую PDF-схему. Для генерации схемы применяются функции библиотеки TCPDF: ImageSVG — для вставки SVG-изображений, Rect — для рисования прямоугольников, Text — для вывода текста, Line — для рисования линий.

Кусочек схемы сборки
Две части схемы сборки поделки

В схему включается визуализация поделки, количество пинов каждого диаметра, название торговой марки и QR-код. Новая схема длительное время хранится в облаке и доступна для скачивания по этому QR-коду, для генерации которого используется библиотека php-qrcode.

Помимо эстетического удовольствия у взрослых, сборка поделок развивает мелкую моторику у детей младшего возраста, что положительно влияет на речь и интеллект. Детям среднего возраста важно не проводить все время за компьютером или в телефоне.