Подтвердить что ты не робот

Рисование 1-пиксельной толщины с псевдонимом в режиме реального времени

Краткая информация: я работаю над веб-приложением рисования, и один из инструментов, которые я реализую, представляет собой карандаш толщиной в 1 пиксель. Инструмент позволяет пользователю нарисовать линии на 1 пиксель с псевдонимом на холсте.

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

ПРИМЕЧАНИЕ. Алгоритм Брешенема не будет работать для этой ситуации. Мой ввод представлен в режиме реального времени, поэтому я не рисую строку от P0 до P1, где расстояние между P0 и P1 составляет много пикселей. В общем случае P1 является соседом P0.

Проблема в том, что мои результирующие строки не имеют абсолютно чистого веса 1px. Вот пример:

Line comparison

Обратите внимание, что обе линии рисованы вручную, поэтому существует некоторая дисперсия. Интересно то, что Photoshop может сделать намного более чистое 1px представление строки, которую я рисую. Причина, по которой моя линия выглядит более грязной, заключается в следующем:

Photoshop's line

My line

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

Итак, вопрос, который мне оставил, заключается в том, как Photoshop может пропускать красные пиксели, которые появляются в моих линиях. Единственное, о чем я мог думать, это ждать, пока два пикселя не будут поставлены в очередь, прежде чем рисовать любой из них, чтобы я знал, прошел ли "сосед". В этом случае я бы просто не рисовал первый из двух пикселей, потому что он был бы эквивалентен красному пикселю на моей диаграмме. Это рискует не рисовать намеченный пиксель, если пользователь рисует пиксель, перемещает курсор на один пиксель на юг, а затем на один пиксель на восток. Оба пикселя должны быть нарисованы, но алгоритм сказал бы иначе.

Любые идеи? Как Photoshop может решить эту проблему?

4b9b3361

Ответ 1

Оригинал. Посмотрите на алгоритм линии Bresenham. Он может легко продлиться относительно сглаживания и т.д.

Изменить. Что касается разработки вопроса и обсуждений (особенно комментариев ниже), я хотел бы выделить несколько интересных моментов: инструмент для карандашей Photoshop также рисует очень похожие строки с "восточным" и "юго-восток", если мышь перемещается относительно медленно, тем самым обеспечивая множество выборок для всех этих пикселей. Как только мышь перемещается быстрее, траектория не предоставляет выборки для всех непосредственно соседних пикселей. Тогда результатом будет желаемая линия с толщиной в 1 пиксель. В заключение отметим: "Никакого" волшебства "за инструментом Photoshop для карандашей нет; он просто сканирует меньше выборок. Подробнее см. В обсуждениях/комментариях ниже.

Ответ 2

Разница между обеими линиями в основном заключается в том, что Photoshop пересматривает пиксель n-1, нарисованный ПОСЛЕ рисования пикселя n, и стирает его, если он дает положительный результат с одной из следующих масок:

 x 1 x       x 1 x
 1 o x   or  x o 1
 x x x       x x x

или

 x x x       x x x
 1 o x   or  x o 1
 x 1 x       x 1 x

x = Не против
o = n-1 пиксель
1 = Маркированный пиксель после рисования пикселя n

Или написано как логика:

Предположим, что пиксель n-1 находится в [i, j], поэтому после маркировки пикселя n проверьте:

If ( (a[i-1,j  ]==1 && a[i  ,j-1]==1) ||
     (a[i-1,j  ]==1 && a[i  ,j+1]==1) ||
     (a[i  ,j-1]==1 && a[i+1,j  ]==1) ||
     (a[i  ,j+1]==1 && a[i+1,j  ]==1))
Then
     Unmark a[i,j];

Возможно, вы захотите, чтобы ваша линия задерживала один пиксель, чтобы не показывать ваши "исчезающие" пиксели (хотя я сомневаюсь, что это будет заметно в этом масштабе).

alt text
.

Ответ 3

Я думаю, вы, наконец, решили свой вопрос (прошло 6 лет...), но я просто хотел сказать, что ваше приложение, похоже, работает на самом деле лучше, чем Photoshop в этом конкретном случае. Хотя я думаю, что я знаю, какова была ваша цель (избегая этих кластеров пикселей), "постоянная толщина" лучше достигается с помощью вашего приложения (несмотря на нежелательные группировки), в то время как Photoshop создает образец "колбасной веревки", который может быть более умным, но нет так что они являются постоянными по ширине и, следовательно, не столь "реальными". Вероятно, это связано с другой обработкой десятичных значений (округление) и выбором того, какие пиксели заполнять или пропускать. Но опять же, это старая тема.