Pull to refresh

Мои экзерсисы2. PaintUp — раскраска разноцветных эскизов online

Reading time4 min
Views1.5K
image
Некоторое время назад я писал о своем android-приложении раскраске и онлайн-галерее для публикации эскизов и картин из приложения. Идея браузерной онлайн-раскраски вполне логична, но как-то не было стимула сесть и сделать. Было очевидно, что придется использовать технологии, с которыми я не работал и это не сильно вдохновляло. Но как-то появилось время и я решил попробовать. Забегая наперед скажу, что в процессе вскрылись достаточно неочевидные свойства браузеров. Выяснилось, что есть онлайн-компиляторы (в частности с++), выдающие исполняемый файлы для windows и linux. И кроме того мне пришлось впервые поставить себе Linux (Ubuntu).

Итак, основное пожелание заключалась в том, чтобы постараться скрыть сам алгоритм раскраски. Как следствие реализация алгоритма на JS отпадает. Остается либо использование другой браузерной технологии, либо оставить браузеру только рисование, а раскраску «считать» на сервере.

Первое что приходит в голову – flash. Он в какой-то мере позволяет защитить код и при этом в одном приложении можно совместить и рисование, и раскраску. Но с флешом я вообще никогда не работал. Установил триальный adobe flash, скачал похожий пример и… как-то с флешом у меня не заладилось. Пришлось пока этот вариант отложить и попробовать что-то другое.

Следующим вариантом было браузерное приложение на Java. Но он отпал из-за необходимости для работы приложения запуска дополнительного софта.

Так я плавно подошел к варианту браузерного рисования и серверного счета.

Браузерное рисование – это canvas либо svg. Но выясняется очень плохая с точки зрения алгоритма раскраски особенность браузеров. При рисовании линий используется не отключаемый antialiasing. Сначала были попытки борьбы с этим программной заменой всех хоть сколько-нибудь прозрачных пикселей цветом фона. Но как оказалось прозрачность – это не все. Сглаживание происходит не только при помощи прозрачности – а и по цвету. То есть нарисованная и «обезпрозраченная» одноцветная линия в своем составе имеет пиксели, отличающиеся по одной или нескольким компонентам RGB до 5 единиц. В моем случае это серьезная проблема, поскольку алгоритм должен получить для одноцветной линии все пиксели одинакового цвета. И решается она двумя способами. Либо предобработкой с искусственной заменой «похожих» пикселей на пиксели нужного цвета, либо попиксельным рисованием. Выбран был второй путь – рисование через putImageData. Пришлось, правда, написать функцию поиска пиксельной «прямой», соединяющей две точки.

Ок, с рисованием в первом приближении все понятно. Для передачи изображения на сервер используем jquery. Теперь серверный солвер.

Сперва я портировал алгоритм раскраски с С++ на PHP. Получилось очень дорого – даже небольшого размера изображение (200х300) при двух цветных линиях раскрашивается около 40 секунд. Такой хоккей нам не нужен. Поэтому начинаю думать в сторону C++ приложения, которое либо крутится на сервере как служба, либо запускается PHP-контроллером. Здесь сложности были уже организационные. Во-первых для запуска службы нужно помимо того что располагать выделенным сервером с рут-правами, еще и уметь его администрировать. А я, к сожалению, нужными скилзами не обладаю. Вот тут мне первый раз очень повезло. На одном из моих «обычных» хостингов оказалась доступной возможность запускать в PHP exec. Дело оставалась за сборкой утилиты под linux. К сожалению и тут у меня достаточного опыта не было, поэтому я потратил какое-то время на поиск онлайн-компиляторов. Нашел только один www.onlinecompiler.net, и то без возможности компилировать многофайловые проекты. Но его хватило для тестов (удавалось вызвать по http скрипт-контроллеп, который запускал пустую программу и возвращал значение).

Отступать было поздно, и я решил попробовать поставить ubuntu. Скачал образ, запустил его через vmware и начал читать литературу по «теме компиляции проектов в линуксе» :) Здесь мне повезло второй раз, потому как практически с пол-пинка мне удалось скомпилировать мой проект в исполняемый файл.

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

Дело было за малым. Выложить на сервер index.php с рисовалкой на js, выложить solver.php на который браузер шлет «задание» и получает раскраску, выложить и установить флаги исполнения для исполняемого a.out ну и так, по мелочам.

И цепочка ожила.
В результате JS позволяет нарисовать задание и отправляет его в виде PNG-файла с использованием AJAX на серверный PHP-контроллер. Контроллер принимает PNG, открывает его, делает некоторую предобработку, сохраняет результат во временный BMP и натравливает на него ./a.out. Тот открывает BMP, делает раскраску, сохраняет результат в новый BMP и передает управление обратно в PHP-контроллер. Контроллер открывает результат, жмет его в JPEG, удаляет все промежуточные файлы и отдает ожидающему ответа http-запросу адрес JPEG-картинки. Клиентский JS, получая адрес картинки, создает тег и демонстрирует пользователю в браузере результат всей работы.

Данная схема конечно далека от идеала. И дело даже не в том, что приличную часть манипуляций с файлами можно передать на сторону С++. По-хорошему приложение должно крутиться службой. Ну или в крайнем случае использоваться как расширение php. Но это не мешает ощущать чувство завершенного гештальта :)

PS: Желающим поклацать – тестовый вариант сборки. Для снижения нагрузки (а это обычный шаред хостинг) размер «задания» ограничен 250х350 пикселей, а количество цветов 15-тью. Рисуете минимум две цветных линии, жмете PaintUp и получаете раскраску. Просьба, не злоупотреблять :)

PPS: Раскраски будут удаляться, поэтому если хотите оставить на память — сохраняйте локально.
Tags:
Hubs:
+21
Comments7

Articles

Change theme settings