Алгоритм для размазывания инструмента? - PullRequest
2 голосов
/ 23 октября 2010

Я пытаюсь реализовать инструмент размазывания, подобный тому, который вы найдете в Gimp или Photoshop.Я пробовал много вариантов, но у всех есть проблемы.Базовый метод, который я пробовал для размывания от положения P1 до P2 на изображении:

  1. Скопируйте прямоугольник размером с текущую кисть из P1.
  2. Нарисуйте этот прямоугольникP2 с низкой непрозрачностью.

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

Если это имеет значение, я работаю на мобильном устройстве (Android, Java), поэтому что-то быстрое было бы предпочтительным.

Ответы [ 3 ]

3 голосов
/ 24 октября 2010

Я подозреваю, что ваш алгоритм постоянно визуализирует ваши прямоугольники друг над другом, вероятно, усредняя их значения, чтобы получить новое значение цвета ниже. В зависимости от того, как настроены особенности вашей программы, я бы поспорил, что значения RGB будут равны 0x000000 из-за повторного усреднения. Это также объясняет, почему меньшие расстояния шага чернеют быстрее, так как больше шагов равняется большему усреднению. У меня была похожая проблема с устройством смены цвета, которое неоднократно было размыто и чернело по краям.

Хороший учебник по созданию собственного инструмента размазки можно найти здесь: http://losingfight.com/blog/2007/09/04/how-to-implement-smudge-and-stamp-tools/

К сожалению, все примеры приведены в Objective-C, но текст довольно хорошо объясняет, что происходит.

Надеюсь, это поможет.

1 голос
/ 22 июля 2011

Ваша проблема в том, что Android использует предварительно умноженную альфа для растровых изображений. Альфа-канал умножается на RGB, чтобы сэкономить время при компоновке.

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

Demonstration of the premultiplied alpha effect in rendering with Android

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

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

Альфа- и rgb-каналы должны отображаться отдельно в непрозрачных растровых изображениях, а затем как-то рекомбинироваться. К сожалению, в Android пока нет хорошего способа сделать это.

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

0 голосов
/ 22 ноября 2016

довольно старая тема, но у меня возникла та же проблема (пятно становится черным).Я также следовал этому уроку:

http://losingfight.com/blog/2007/09/05/how-to-implement-smudge-and-stamp-tools/

Как упоминает GuyNoir, проблема заключается в том, что проблема заключается в предварительно умноженном альфа для растровых изображений в Android, где значения цвета, хранящиеся в памяти, уже умножаются на альфа значение,Bluring страдает от той же проблемы в виде темного ореола между прочим.

Нет никакого способа обойти это с помощью API холста, так как:

"Могут быть нарисованы только предварительно умноженные растровые изображениясистемой представления или Canvas. "

Таким образом, мы должны извлечь пиксели с помощью Bitmap # getPixels () и выполнить смешивание вручную.Это определенно влияет на производительность, но это не так сложно реализовать.

, поэтому для каждого пикселя:

alpha = ( SourceAlpha * strength ) + ( DestinationAlpha * ( 1 - strength ) )

color = ( SourceColor * strength ) + ( DestinationColor * ( 1 - strength ) )

Назначение - изображение, которое нужно смазать, а источник - кисть.Сила показывает, насколько сильно вы нажимаете на пятно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...