处理 alpha 透明度的高斯模糊
本文关键字:高斯 模糊 透明度 alpha 处理 | 更新日期: 2023-09-27 18:31:57
我一直在尝试用 C# 实现一种算法,用于处理透明度的高斯模糊。我尝试了以下两种实现,每种实现似乎都给了我不同类型的结果。但两者都没有考虑阿尔法通道。
http://code.google.com/p/imagelibrary/downloads/detail?name=ImageLibrary-source-1_2_4.zip&can=2&q=http://www.smokycogs.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/
我的测试图像在透明背景 PNG 上有一个简单的圆圈。
有人可以指出我正确的方向,让高斯模糊处理具有透明度的图像吗?我能找到的唯一链接是一个盒子模糊。http://www.codeproject.com/Articles/6162/Gausian-and-Alpha-Blurring
如果您使用的是预乘 alpha 透明度,则可以像 RGB 通道一样模糊 alpha 通道。
如果您的 alpha 没有预乘,您可能会得到奇怪的边缘伪像。 为避免这种情况,您可以尝试将图像转换为预乘,过滤它,然后将其转换回来。 这个过程存在陷阱,但结果可能比天真地平滑未乘的 alpha 图像要好。
每个 RGB 值与 alpha 值相乘,然后将结果除以最大可能的 alpha。
假设您只想平均三个像素:
newBlue = (
src[-1].Blue * src[-1].Alpha +
src[0].Blue * src[0].Alpha +
src[1].Blue * src[1].Alpha ) / (255*3);
如您所见:如果所有三个像素都是实心的(alpha = 255),那么与忽略alpha通道(这确实是我们想要的)相比,此计算不会产生任何影响。
这是一个没有 alpha 的 3x3 卷积:
for (var i = nWidth - 2; i > 0; i--)
{
n = ((((pT[-sourcePixelSize]*m.TL) + (pT[0]*m.TM) + (pT[sourcePixelSize]*m.TR) +
(pM[-sourcePixelSize]*m.ML) + (pM[0]*m.MM) + (pM[sourcePixelSize]*m.MR) +
(pB[-sourcePixelSize]*m.BL) + (pB[0]*m.BM) + (pB[sourcePixelSize]*m.BR) + 5)/m.Factor) + m.Offset);
*pD = (byte) (n <= 0 ? 0 : n >= 255 ? 255 : n);
pT += sourcePixelSize;
pM += sourcePixelSize;
pB += sourcePixelSize;
pD += 4;
}
这是带有 alpha 的 eqvivalent:
for (var i = nWidth - 2; i > 0; i--)
{
alphaSum = (pT[-4 + ao] + pT[ao] + pT[4 + ao] +
pM[-4 + ao] + pM[ao] + pM[4 + ao] +
pB[-4 + ao] + pB[ao] + pB[4 + ao] + 5)/9;
n = alphaSum != 0
? ((((pT[-4]*pT[-4 + ao]*m.TL) + (pT[0]*pT[ao]*m.TM) + (pT[4]*pT[4 + ao]*m.TR) +
(pM[-4]*pM[-4 + ao]*m.ML) + (pM[0]*pM[ao]*m.MM) + (pM[4]*pM[4 + ao]*m.MR) +
(pB[-4]*pB[-4 + ao]*m.BL) + (pB[0]*pB[ao]*m.BM) + (pB[4]*pB[4 + ao]*m.BR) + 5)/
(m.Factor*alphaSum)) + m.Offset)
: 0;
*pD = (byte) (n <= 0 ? 0 : n >= 255 ? 255 : n);
pT += 4;
pM += 4;
pB += 4;
pD += 4;
}