2010-10-23 237 views
2

我试图实施一个涂抹工具,就像你会在GIMP或Photoshop中找到的一样。我尝试过很多变化,但都有问题。我尝试过在图像上从位置P1到位置P2的模糊的基本方法是:涂抹工具算法?

  1. 从P1复制当前画笔大小的矩形。
  2. 在低透明度的P2上画这个矩形。

它看起来很好,如预期的污迹,但我遇到的主要问题是,污迹似乎使事情变得更暗。特别是使用小刷子间距时,重复的污迹会将该区域变成黑色。任何关于我在做什么错误的建议或我可以看到的一些标准算法?我看了一下Gimp的来源,但很难跟踪。

如果很重要,我正在使用移动设备(Android,Java),所以快速更好。

回答

3

我怀疑你的算法不断呈现你的矩形在彼此的顶部,可能平均他们的价值观以获得新的颜色值。根据你的程序设置的具体情况,由于这种重复的平均,我会保证RGB值将变为0x000000。这也解释了为什么更小的步距变黑速度更快,因为更多的步数等同于更多的平均值。我遇到了一个类似的问题,换色器在边缘反复模糊变黑。

上创建自己的涂抹工具一个很好的教程,可以在这里找到:http://losingfight.com/blog/2007/09/04/how-to-implement-smudge-and-stamp-tools/

不幸的是,这些例子都是在Objective-C,但文字解释相当好到底是怎么回事。

希望这会有所帮助。

+0

感谢您的提示。您能否提出在将污迹图像重新混合到目标图像上时我可以做些什么,使其不会变黑?我实际上已经阅读过几篇教程(这是我能找到的唯一一本!),我看不出他对我的做法有什么不同。他没有提到混合模式。有任何想法吗? – RichardNewton 2010-10-24 16:00:18

+0

我从事计算机图形学工作已经有相当长的一段时间了,但是在这里。从我所知道的情况来看,这个问题是由于你的不透明性引起的。你是如何真正执行这部分变换的?如果我们将这些价值观念推向极致,那么就有几种不同的可能性。例如,蓝色和自身的平均值应该总是会让你变成蓝色,就像固体块被弄脏了一样。现在,如果将蓝色拖入红色会发生什么情况?理论上,你应该得到紫色。重复的污迹应该给你更均匀的紫色,直到你达到0xFF00FF。 – phobos51594 2010-10-24 18:27:20

+0

感谢您的回复。我所做的只是使用标准绘制位图程序(从而将位图从前一位置绘制到新位置,并将alpha设置为X百分比)(因此位图将显示在第一个稍微透明的上方)。蓝色变成红色确实会变成紫色。奇怪的是,我可以分别擦紫色,红色和蓝色,而且不会变暗。然而,摩擦紫色和蓝色重叠的位置会迅速产生黑色(紫色+红色不是这种情况),并且摩擦任何带有黑色的物体会迅速产生更多的黑色。 – RichardNewton 2010-10-25 01:31:53

1

你的问题是,Android使用预乘alpha的位图。 Alpha通道与RGB相乘以节省合成时间。

这是一个问题的例子。这两个刷子都是完全一样的,除了底部被渲染为5%alpha。

Demonstration of the premultiplied alpha effect in rendering with Android

创建涂抹工具时,如何进入此是涂抹正在呈现非常低的阿尔法像素(通常是从掩蔽效应,或简单地从原始位图本身)。当许多这些位图呈现在彼此之上时(如在涂抹中),它变成灰色。

我在为Android编写的照片编辑应用程序构建一个涂抹工具时遇到了此错误,但遗憾的是还没有找到一个好的解决方案。

alpha和rgb通道需要在不透明的位图中分别渲染,然后以某种方式重新组合。不幸的是,目前在Android中似乎没有好的方法。

如果你想出了一个解决方案,我很乐意听到它。希望这会给你一些关于这个问题的原因的信息,也许是一些修复的灵感。

0

很老的话题,但我发现自己有同样的问题(涂抹黑色)。我还以下这个教程:

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

作为GuyNoir提到,问题是对于其中存储在存储器中的颜色值已经由α值乘以在机器人的位图预乘阿尔法。顺便提一下,Blured受到黑暗光环形式的同样问题的困扰。

有没有办法解决这个因为用画布API:“只有预乘的位图可通过查看系统或画布绘制”

所以我们必须通过位图#getPixels()提取像素并手动进行混合。这绝对会对性能产生影响,但实现并不难。

所以对于每个像素:

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

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

目的地是涂抹的图像与源是刷。 这个力量代表了你在涂抹画笔上的压力。