Привет тебе!

Давным-давно, в одной соцсети наткнулся я на интересное приложение. Это была коллаборативная онлайн-рисовалка: что-то в духе flockdraw.com и webcanvas.com, только русскоязычная и с меньшим количеством пользователей. Да, собственно, я вот об этой игре говорю. Сейчас, конечно, там практически никого не бывает, и вам дико повезёт, если, зайдя туда, вы обнаружите в игре кого-то помимо себя. А году эдак в 2007 человек за сто точно было онлайн и днём и ночью. Людей это дело реально развлекало, причём от мала до велика. Круто считалось нарисовать что-то реально красивое, ведь все видели сам процесс твоего рисования, могли выразить восторг, могли что-нибудь пририсовать, а могли и испортить. Из инструментов — смешно вспомнить — тогда был только карандаш (pen) и рука (pan) для прокручивания бесконечного полотна, даже линии прямой нельзя было нарисовать. Ни тебе ластика, ни настройки цвета или толщины линии. Чата тоже не было, так что общались так: писали текст прямо на канве рисования, получалось жутко долго и очень коряво; ведь мышка — далеко не идеальный инструмент для рисования от руки. Другие игроки отвечали тебе таким же корявым рукописным текстом ниже под твоей надписью; ещё ниже — следующие, и холст превращался в сплошную стену наполовину неразборчивых каракулей, благо стена бесконечная. Вот такие весёлые времена были когда-то.

В этой игре особенно крутыми были те, у кого в распоряжении имелся графический планшет. Они писали уже не мышкой, а естественно, от руки — красиво, быстро и чистенько, да и рисунки у них были на порядок лучше. Никто с мышкой не мог их переплюнуть, в том числе и я, ведь у меня планшета не было. Так что ваш покорный слуга первые недели три развлекался мышью, но потом такой ход дел мне надоел и захотелось мне быть не боярыней дворянскою, а владычицей морскою не лохом с мышкой, а крутым художником, и не просто красиво рисовать наравне с владельцами планшетов, а уделать и их как сынков и рисовать очень сложные рисунки быстро и без помарок.

Вначале я стал тренироваться «на кошках»: взял в распоряжение метаскриптовый язык AutoIT под Windows и написал на нём пару очень простеньких программ. Первая рисовала просто окружность, а вторая — прямую линию: программно ставила курсор мыши в определённое место, программно зажимала левую кнопку мыши и программно вела курсор по прямой или кривой. Приложение, в котором осуществлялись такие действия, «думало», что это пользователь двигает мышку и нажимает кнопки, но на самом же деле всё рисовал робот AutoIT (что-то типа cnc-станка). Браузер интерпретировал движения и нажатия в контексте игры как процесс рисования и игра транслировала нарисованное (команды) на сервер. Другие пользователи понятия не имеют, что рисунок осуществляет не человек, а робот. Вот такая хитрость =) По сути — бот!

Таким образом, я научился рисовать идеальные окружности и прямые линии. С такими технологиями в руках я был гуру даже для людей с планшетом, ибо даже используя стилус не нарисуешь идеальную окружность. А уж для школьников (а подваляющее большинство играющих было именно школьники) я был прямо-таки неким божеством художественных искусств. И в моих руках теперь были буквально инопланетные технологии рисования! Меня дико развлекало то, что на каждый нарисованный мною идеальный круг набрасывалась целая толпа и превращала его то в рисованного смешарика, то в часы, то в рожицу, то в какой угодно другой рисунок, в основе которого был круг. Оставшиеся же разделились на два лагеря: те, кто завидовали мне и моим умениям, и те, кто восхищались. Завидовывшие из злости писали «читер» и портили все мои художественные начинания, ну а восхищающиеся перечёркивали высказывания завидующих и выражали восторг в письменной форме: «воу круто», «как у тебя это получается?», «это планшет?», «какая программа?» и так далее... меня попёрло!

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

McPaintio — это программа, преобразующая изображение в набор мышиных команд, рисующих это самое изображение. Эдакий мета-рисовальщик. А раз любое изображение можно аналитически перерисовать, то есть возможность нарисовать что угодно в любой канве любого приложения! Представьте, что вы берёте рисунок с замысловатым орнаментом и немедленно рисуете сложнейший сплайн, описывающий этот орнамент, например, прямо в окне 3DS Max! Не правда ли, это реально круто?!

Разработка продолжалась весьма долго, но я реально заморочился и оснастил McPaintio клёвыми фишками. Например, если рисунок, который необходимо нарисовать, больше, чем канва для рисования, которую предоставляет приложение, и при этом приложение поддерживает операцию pan, то McPaintio может нарисовать изображение поблочно, переключая в нужные моменты времени инструменты pan и pen и рисуя правильные фрагменты в правильных местах холста! В McPaintio присутствуют аж три разных алгоритма рисования, предназначенных для выполнения разного рода трассировок изображения и перенесения его в другую канву. Эти алгоритмы в различной степени соответствуют различным скоростям и точностям рисования. Я также оснастил McPaintio возможностью рисования изображений в оттенках серого несколькими различными алгоритмами. Например, если требуется нарисовать изображение в оттенках серого и канва предоставляет инструмент выбора цвета, то можно настроить McPaintio так, чтобы он сам открывал палитру в приложении, выбирал нужный цвет, закрывал палитру и продолжал процесс рисования нужным цветом. McPaintio также умеет писать пользовательский текст и имеет в арсенале гибкую настройку кнопок управления и таймингов, позволяющую подстроить процесс рисования под самые требовательные приложения.

В общем, поработал я на славу, правда, приложение получилось с ужасным интерфейсом: это результат неправильного планирования архитектуры, ибо с течением времени в произвольном порядке дописывались всё новые функции и так или иначе отпечатывались на общем виде программы. Получилась адовая куча-мала из полей, галок и переключателей, а переделывать уже лень. Но меня это совершенно не колышит, ведь McPaintio — моя программа, созданная мною для меня, а раз лично я интерфейс понимаю, то большего мне и не надо! Пробегусь в кратце по функционалу и продемонстрирую вам возможности.

Пример 1.

Начнём с самого простого. Скачали приложение (проверили его размер) и открываем простой чёрно-белый bmp-файл. Необходимо транслировать из файла то, что нарисовано чёрным, в другую канву. Пока что для подопытной канвы выберем канву Microsoft Paint. Будем рисовать первым из представленных алгоритмов — «к ближайшей точке». Этот алгоритм движет перо от текущего пикселя в сторону ближайшего ещё не закрашенного, закрашивая все промежуточные по пути. Если таких ближайших незакрашенных пикселей несколько, то выбирается случайный из них. Начинается рисование в одном случайном пикселе из множества ещё не закрашенных. В определённые моменты времени происходит перескок в новый случайный ещё не закрашенный пиксель (этот специально запрограммированный артефакт служит цели подстройки под интерфейс ещё первой программы колаборативного рисования, в которой ограничивалась длина максимальной линии, которую пользователь может нарисовать). Настраиваем кнопку старта трансляции на F10 (по умолчанию), а остановки — на F12. Сначала пробуем рисовать прямо в самом McPaintio (для наглядности). Ставим мышь примерно в верхний левый угол рисунка и жмём F10. Видим, как движется мышь. В заголовке программа показывает количество частей (разрывов линии, подъёмов левой кнопки мыши), которые она произвела. В этот момент программа полностью перехватывает управление мышью, и даже если я буду пытаться ей шевелить, у меня ничего не выйдет, так как в уже следующий тик мышь будет программно перемещена в нужную программе точку. Фиолетовым видим уже закрашенные пиксели изображения. Происходит процесс закраски, который в любой момент можем остановить, нажав на F12. Можно заметить, что расстояние между ближайшими закрашенными пикселями не равно единице. Складывается впечатление, что программа пропускает некоторые пиксели. На самом деле это действительно так и это не ошибка, а ещё один специально запрограммированный артефакт, который служит цели подстройки под интерфейс программы колаборативного рисования, в которой радиус пера составлял 2 пикселя. А раз так, то, закрасив пиксель (x, y), нет смысла закрашивать пиксели (x + 1, y) и (x, y + 1); их можно просто пропустить, так как на холсте они уже закрашены. Для игнорирования этого артефакта и принудительной обработки абсолютно всех пикселей служит галка «точно».

Когда показательный прогон показывает приемлемый результат, не дожидаясь окончания рисования останавливаем программу и переходим в Paint. Ещё раз: необходимо транслировать из файла то, что нарисовано чёрным (а не белым). Черное — это пиксели с интенсивностью 0, белое — это пиксели с интенсивностью 255. McPaintio позволяет выбрать обрабатываемые (рисуемые) пиксели по их интенсивности, и не просто одну конкретную интенсивность (скажем, 0), а даже диапазон. Сделано это было для того, чтобы корректно отрисовывать даже необработанные изображения, в которых, как правило, интенсивность самых тёмных пикселей не точно равна 0, а имеет некторый разброс значений около нуля из-за погрешностей сжатия изображений. Тогда, указав диапазон, например, [0..8], программа корректно отрисует «чёрное». Для указания диапазона используются поля «расслаивать» — указываем чёрное как [0..8] и рисуем наш файл уже кистью в Paint.

Пример 2.

Тут я более наглядно показываю выбор разных диапазонов для рисования. Рассмотрим простой градиент: слева — чёрное, справа — белое. Если выбрать диапазон [0..8], то, как я уже говорил и показывал, будет осуществляться рисование левой области градиента. Если же выбрать, скажем, [128..132], то будут отрисованы пиксели примерно из середины. И, наконец, если выбрать [242..255], то будут нарисованы самые правые участки градиента. Выбираем диапазон [0..32] и включаем рисование в Paint. Обратите внимание на то, насколько широкая часть полосы отрисовывается. Обратите внимание также и на то, что правый край полосы не ровный, а рваный. Это связано с тем, что градиент был подготовлен в Photoshop с использованием дизеринга. Посмотрите как перо плотно обтекает уже отрисованные участки.

Пример 3.

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

Пример 4.

Теперь откроем новое изображение, являющееся контуром предыдущего. Хочу продемонстрировать рисование в «быстром» режиме, в котором отсутствуют дополнительные задержки в коде рисования. Они нужны для того, чтобы «медленные» программы типа Photoshop без пропусков воспринимали пересылаемые извне команды рисования (мною было замечено, что некоторые программы рисования отбрасывают часть оконных сообщений, посланных им, если не успевают производить обработку предыдущих команд). Итак, открываем файл, ставим галку «быстро» и рисуем для большей наглядности в самом McPaintio. Обратите внимание на скорость рисования. Это максимальная скорость, с которой рисует McPaintio в этом режиме.

Пример 5.

Настало время продемонстрировать новый алгоритм рисования — «динамика линий». Этот алгоритм движет перо от текущего пикселя в сторону максимально отдалённого ещё не закрашенного пикселя, закрашивая все промежуточные по пути. Максимально отдалённый ещё не закрашенный пиксель выбирается не произвольным образом, а с некоторым ограничением: от него до текущего пикселя должна существовать прямая линия, проходящая а) только по обрабатываемым пикселям б) число уже закрашенных пикселей в линии не должно превышать 30% от общего числа пикселей линии. Такая техника максимально напоминает естественное рисование человеком от руки и была введена взамен старого алгоритма «к ближайшей точке», который уж слишком явно разоблачал в программе колаборативного рисование факт рисования не человеком, а роботом. Сначала рисуем для большей наглядности в самом McPaintio, а потом кистью в Paint.

Пример 6.

Продемонстрирую теперь этот алгоритм на примере градиента. Буду рисовать два раза, в двух разных диапазонах. Чтобы итоговая картина получилась без разрывов, необходимо в обеих процедурах рисования поставить курсор мыши точно в определенную позицию (точку привязки). Отмечу точку привязки в Paint'е красным крестиком. Сначала открываю градиент и выбираю диапазон [0..8]. Это нарисует самый левый фрагмент градиента. Снимаю галку «быстро» и устанавливаю курсор как можно ближе к точке привязки. Обратите внимание, что процесс закрашивания большого прямоугольника очень напоминает движение кисти человека. После окончания рисования выбираю диапазон интенсивности, следующий сразу за текущим — [9..12]. Для наглядности выбираю в Paint'е другой цвет. Опять помещаю указатель в точку привязки и рисую. Обратите внимание, что новые линии расположились строго правее предыдущего рисунка, причём впритык. В этом и есть суть выбора рисуемого диапазона в этом режиме.

Пример 7.

Продемонстрирую теперь два таких параметра, как «пауза подъема мыши» и «время линии». McPaintio позволяет выставлять время, которое нужно рисующей программе на то, чтобы воспринять линию и отрисовать её. Этот параметр называется «пауза подъёма мыши» и выражается в миллисекундах. Он фактически говорит McPaintio: «после проведения очередной линии отпусти левую кнопку мыши и подожди n миллисекунд», где n - задаваемый параметр. Дело в том, что такие программы, как, например, Paint не пропускают и не отбрасывают оконные сообщения, которые были им посланы. Paint — это сверхпростая и сверхскоростная программа рисования, поэтому при её использовании значение паузы можно устанавливать даже в 0. Но есть такие грузовые программы, как, например, Photoshop, которые медленно рисуют линии (особенно гауссовыми мягкими кистями), ведут историю и нагружены ещё целой кипой пре- и пост-рисовательных действий. Они могут пропускать оконные сообщения, посланные им. Для таких программ «паузу подъема мыши» приходится устанавливать на уровне 100 миллисекунд, чтобы они успели сообразить что надо делать и сделали это.

Аналогичным целям служит параметр «время линии», который говорит сам за себя: это то время, за которое рисуется одна прямая линия, в миллисекундах. Например, для при использовании Paint'а можно устанавливать этот параметр в 10 (или даже 5), тогда как для Photoshop'а он должен равняться 50 (или даже 100). Иначе Photoshop ещё не успеет отрисовать линию, как извне уже придут сообщения о рисовании следущей линии. В результате Photoshop порвёт текущую линию, пропустив часть оконных сообщений.

В видео я вначале выставляю эти параметры в 0 и 1 соответственно. Обратите внимание на то, как быстро рисуется изображение. Потом для демонстрации я ставлю эти параметры в 200 и 200. Теперь рисование происходит о-о-очень медленно. Наконец, в конце я ставлю средние значения для большинства программ — 25 и 25: теперь всё в порядке.

Пример 8.

Теперь поиграем с текстом, ведь McPaintio может и писать! Эта функция вводилась для реализации возможности ненапряжного письма для той самой первой программы коллаборативного рисования. В McPaintio есть специальное поле «текст», куда можно вписать текст, затем выбать размер шрифта 40 и нажать кнопку «написать». Программа сгенерировала изображение написанного текста, и теперь на общих основаниях будет его отрисовывать. Включим точный режим и посмотрим что из этого выйдет. Получилось весьма неплохо. Теперь поменяем размер шрифта на 80 и напишем то же самое толстой кистью. Так гораздо лучше!

Пример 9.

Теперь продемонстрирую один из интереснейших режимов рисования — рисование по блокам. Забегая вперёд скажу, что этот режим вводился ради рисования огромных изображений на бесконечном холсте через очень маленькое «отверстие» для рисования для всё той же первой коллаборативной программы рисования. Для подопытных экспериментов сейчас возьмём Photoshop. Итак, есть небольшое окно программы (фактически не больше 512 х 512 пикселей), через которое мы можем иметь доступ к большому холсту (фактически 2000 х 2000 пикселей). Необходимо отрисовать изображение гораздо большее, чем просмотровое окно. Открываем в McPaintio огромное изображение (под стать холсту) и создаём в Photoshop новый документ размером 2000 х 2000 пикселей. Видим холст целиком только при масштабе 30%: при масштабе же 100% видим лишь его малую часть. Далее необходимо показать McPaintio те точки на экране, в которых находятся кнопки включения инструмента панорамирования (pan) и инструмента кисти (pen). Однажды указав их, теперь McPaintio сможет рисовать изображения поблочно сам прокручивая холст в нужные позиции. Для обучения вначале поставим галку «блоки» и укажем размер одного блока 256 х 256 пикселей. То есть McPaintio будет рисовать избражение 1024 х 1024 пикселя через просмотровое окно размером всего 256 х 256 пикселей. Теперь необходимо стать курсором мыши на кнопку pan Photoshop'а, и McPaintio запомнит её (чекбокс возле звёздочки станет отмеченным). Аналогично, необходимо сделать для кнопки pen. Поставим правильные тайминги для Photoshop'а (20 и 20), начнём рисование и полюбуемся поблочной отрисовкой. Сначала отрисовывается верхний левый угол изображения. После окончания отрисовки McPaintio переходит в режим панорамирования и подтаскивает холст так, чтобы новая порция данных отрисовалась впритык к старой. И так далее для всех блоков. В конце видео можно полюбоваться готовым изображением.

Пример 10.

It's online time! Теперь сделаем то же самое, только в той самой коллаборативной рисовалке. Поставим размер блока на этот раз в 512 х 480 и немного переобучим McPaintio кнопкам pan и pen. Любуемся результатом. Обратите внимание, что ни в одной комнате программы ни души! Это свидетельствует о том, что спустя много лет люди понаходили себе более интересные игры, чем коллаборативное рисование.

Пример 11.

Теперь перейдём к серьезному примеру! Необходимо отрисовать полноценное изображение в оттенках серого, а не чёрно-белое, как это было до сих пор. В качестве канвы для рисования будем использовать граффити ВКонтакте. Открываем изображение и включаем режим рисования «отложенная техника». Этот алгоритм на самом деле — это то же самое, что и «динамика линий», но за одним исключением. В этом алгоритме в начале McPaintio рисует наиболее длинные серии линий, а в конце — наиболее короткие, тогда как в «динамике линий» это зависит от рандома. То есть «отложенная техника» — это отсортированная по длине линий «динамика линий», вот и всё.

Итак, открыли изображение. Но ранее мы видели, что McPaintio умеет рисовать только один диапазон. Да ещё и только одним цветом, выбранным в рисующей программе. Неужели чтобы отрисовать изображение в оттенках серого нам придётся вручную выставлять диапазон [0..0], выставлять в рисующей программе нужный цвет кисти (чёрный), отрисовывать всё чёрное, потом ставить диапазон [1..1], снова выставлять в рисующей программе нужный цвет кисти, снова рисовать, и так далее до 255? На самом деле, конечно же нет! Во-первых, такое точное разбиение диапазона интенсивностей весьма избыточно, то есть, вместо набора диапазонов {[0..0], [1..1], [2..2], ... , [255..255]} можно использовать диапазон не с шагом 1, а с шагом, скажем, 8: {[0..8], [9..16], [17..24], ... , [248..255]}. Для некоторых изображений подходят шаги 16 или даже 32: меньше будет возни. Правда, и финальное изображение будет подвергаться эффекту постеризации, но в разумных пределах это воплне допустимо. Например, с шагом 8 вы даже не заметите разницы. Наконец, во-вторых: программу McPaintio можно обучить автоматически открывать цветовую палитру, выбирать нужный цвет, закрывать палитру и переключать диапазоны с определённым шагом.

Любопытный зритель, наверное, уже заметил эти странные «+0» возле диапазонов расслаивания. Это и есть настройка шага: устанавливаем как обычно диапазон расслаивания (в данном случае [0..32]), а +0 и +0 на этот раз заменяем на +32 и +32. Это означает, что шаг нижнего и шаг верхнего краёв диапазона после каждой отрисовки будет меняться на +32 уровня интенсивности: сначала программа будет отрисовывать диапазон [0..32], потом [32..64] и так далее до 255. Шаг разумно назначать такой, чтобы диапазоны не перекрывались, а шли стык в стык. Далее настраиваем тайминги 10 и 10 (ввиду того, что граффити ВКонтакте довольно таки резво работают) и ставим галку «градиентно»! Это и включает возможность автоматического шага и выбора цвета из палитры. Обучение автовыбору цвета заключается в указывании McPaintio 4 точек на экране: где находится кнопка «открыть палитру» в рисующем приложении, где в открытой палите находится белый цвет, где в открытой палите находится чёрный цвет, где находится кнопка «закрыть палитру» в рисующем приложении. Указав эти 4 кнопки McPaintio уже сам сможет выбирать цвет текущего диапазона. Замечу, что в некоторых простеньких программах ползунок выбора интенсивности (чёрный — белый) уже вынесен в интерфейс, так что в этом случае нужно указать только 2 точки: «в какой пиксель экрана надо нажать, чтобы выбрать белый цвет» и «в какой пиксель экрана надо нажать, чтобы выбрать чёрный цвет». McPaintio показывает галками «o», «w», «b» и «x» то, что он запомнил расположение открытия, выбора белого, выбора чёрного и закрытия палитры соответственно. Итак, начинаем рисовать и видим, как робот автоматически выбирает нужный цвет и производит рисование.

Пример 12.

Теперь проделаем такой же финт, но в Photoshop'е. Тут уже нужно открывать и закрывать палитру. Научим McPaintio делать это. Настроим тайминги 200 и 10 и полюбуемся прекрасным процессом рисования.

Пример 13.

It's online time again, и на этот раз мы посетим FlockDraw! Нарисуем логотип «AM» прямо на холсте. Для этого выберем знакомую технику и настроим тайминги. Дальше всё просто.

Пример 14.

Ну и на последок предлагаю посмотреть процесс точного рисования довольно большой картины на заказ.