Рисование линий с псевдонимами толщиной 1 пиксель в режиме реального времени - PullRequest
12 голосов
/ 29 декабря 2010

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

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

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

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

Line comparison

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

Photoshop's line

My line

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

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

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

Ответы [ 3 ]

5 голосов
/ 29 декабря 2010

Разница между обеими линиями заключается в том, что 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 голосов
/ 29 декабря 2010

Оригинал : взгляните на алгоритм линии Брезенхэма.Он может быть легко расширен в отношении сглаживания и т. Д.

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

0 голосов
/ 23 октября 2016

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

...