因此,我尝试采用双线性插值算法来调整图像大小并添加 alpha 值。我正在使用 Actionscript 3 来执行此操作,但我并不认为该语言是相关的。

我下面的代码实际上工作得很好,但“擦除”区域周围的边缘似乎变得更暗。有没有一种简单的方法可以让它在找到平均值时不包含我只能假设为黑色(0x00000000)的内容?

代码:

x_ratio = theX - x;
y_ratio = theY - y;
x_opposite = 1 - x_ratio;
y_opposite = 1 - y_ratio;

a = getPixel32(x, y);
be =getPixel32(x + 1, y);
c = getPixel32(x, y + 1);
d = getPixel32(x + 1, y + 1);
alph    = (t(a)  * x_opposite  + t(be)   * x_ratio) * y_opposite + (t(c) * x_opposite  + t(d) * x_ratio) * y_ratio;
red     = (r(a)  * x_opposite  + r(be)   * x_ratio) * y_opposite + (r(c) * x_opposite  + r(d) * x_ratio) * y_ratio;
green   = (g(a)  * x_opposite  + g(be)   * x_ratio) * y_opposite + (g(c) * x_opposite  + g(d) * x_ratio) * y_ratio;
blue    = (b(a)  * x_opposite  + b(be)   * x_ratio) * y_opposite + (b(c) * x_opposite  + b(d) * x_ratio) * y_ratio;

效果图: http://beta.shinyhammer.com/images/site/eraser_pixelborders.jpg

发布解决方案代码!

a = getPixel32(x, y);
be =getPixel32(x + 1, y);
c = getPixel32(x, y + 1);
d = getPixel32(x + 1, y + 1);
asum = (t(a) + t(be) + t(c) + t(d)) / 4;

alph    = (t(a)  * x_opposite  + t(be)   * x_ratio) * y_opposite + (t(c) * x_opposite  + t(d) * x_ratio) * y_ratio;
red     = ((r(a) * t(a) * x_opposite  + r(be) * t(be) * x_ratio) * y_opposite + (r(c) * t(c) * x_opposite  + r(d) * t(d) * x_ratio) * y_ratio);
red = (asum > 0) ? red / asum : 0;
green   = ((g(a) * t(a) * x_opposite  + g(be) * t(be) * x_ratio) * y_opposite + (g(c) * t(c) * x_opposite  + g(d) * t(d) * x_ratio) * y_ratio);
green = (asum > 0) ? green /  asum : 0;
blue    = ((b(a) * t(a) * x_opposite  + b(be) * t(be) * x_ratio) * y_opposite + (b(c) * t(c) * x_opposite  + b(d) * t(d) * x_ratio) * y_ratio);
blue = (asum > 0) ? blue / asum : 0;
有帮助吗?

解决方案

在使用之前,您需要将每个 r、g、b 值乘以相应的 alpha,然后在完成后将这些值除以最终的 alpha。很容易想象当其中一个像素的 alpha 为零时会产生什么效果 - 每个 r、g、b 值都将乘以零,因此它们的原始值是什么根本不重要!他们不会对最终结果做出贡献。

您需要添加一个检查,以便永远不会被零除,并确保舍入误差不会使最终值超过上限。

通常,图像将存储在内存中,其中 alpha 已乘以 r、g、b 值 - 这称为预乘 alpha (维基百科参考).

其他提示

这是使用预乘 alpha 具有巨大优势的领域之一。通过预乘 Alpha,您可以将图像的 RGB 分量视为已提前在黑色上进行预合成。

这消除了与对具有 Alpha 的图像进行任何类型的图像处理相关的许多麻烦的影响,并提供了更快的合成算法。

对于“非预乘alpha”,熟悉的LIRP(线性插值)合成算法是

d = Kf + (1-K)b

...其中 K 是前景的 alpha,f 是前景值,b 是背景。

对于“预乘阿尔法”,您使用

d = f + (1-K)b

...它删除了其中一个乘法,这可以使过程更快(并且硬件更便宜)。需要阅读的关键论文是 Porter 和 达夫的- 《合成数字图像》

如果您使用的是 Windows,则 Win32 阿尔法混合 函数需要预乘 alpha,因此最好尽可能保留在预乘域中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top