所以我试图采用双线性插值算法来调整图像大小并添加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;
答案 0 :(得分:5)
在使用它们之前,您需要将每个r,g,b值乘以相应的alpha值,然后在完成后将值除以最终的alpha值。很容易想象当其中一个像素的alpha值为零时,这将产生的影响 - 每个r,g,b值都将乘以零,因此它们的原始值根本不重要!他们不会为最终结果做出贡献。
您需要添加一个检查,以便永远不会除以零,并确保舍入错误不会使您的最终值超过上限。
图像通常会存储在内存中,而alpha已经乘以r,g,b值 - 这称为预乘alpha(Wikipedia reference)。
答案 1 :(得分:2)
这是使用预乘alpha的巨大优势的领域之一。使用预乘的alpha,您可以将图像的RGB分量视为已事先预先合成黑色。
这消除了与使用alpha的图像上的任何类型的图像处理相关的许多麻烦效果,以及提供更快的合成算法。
对于“非预乘的alpha”,熟悉的LIRP(线性插值)合成算法
d = Kf + (1-K)b
...其中K是前景的alpha,f是前景值,b是背景。
对于“预乘alpha”,您使用
d = f + (1-K)b
...删除其中一个乘法,这可以使过程更快(并且在硬件上更便宜)。要阅读的关键论文是Porter和Duff的 - "Compositing Digital Images"
如果您使用的是Windows,则Win32 AlphaBlend函数需要预乘alpha,因此最好尽可能保留在预乘域中。