Gaussian blur that handles alpha transparency

余生长醉 提交于 2019-12-08 07:31:16

问题


I have been trying to implement an algorithm in C# for a gaussian blur that takes care of transparency. I tried the following two implementations, and each seems to give me different type of results. But neither takes into account the alpha channel.

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/

My test image has a simple circle on a transparent background PNG.

Could somebody point me in the right direction to get the gaussian blur to work with images that have transparency ? The only link i could find was a box blur. http://www.codeproject.com/Articles/6162/Gausian-and-Alpha-Blurring


回答1:


If you are using premultiplied alpha transparency, you can blur the alpha channel just like the RGB channels.

If your alpha is not premultiplied, you can get weird fringing artifacts. To avoid that, you can try converting your image to premultiplied, filtering it, then converting it back. There are pitfalls in this process, but the result will likely be better than naively smoothing a unmultiplied alpha image.




回答2:


You must multiply each RGB value with the alpha value and afterwards divide the result with the maximum possible alpha.

Let's say you want to average just three pixels:

newBlue = (
  src[-1].Blue * src[-1].Alpha + 
  src[0].Blue * src[0].Alpha + 
  src[1].Blue * src[1].Alpha ) / (255*3);

As you can see: if all three pixels are solid (alpha=255) then this calculation won't cange anything compared to ignoring the alpha channel (which is indeed what we want).

Here is a 3x3 convolution without alpha:

            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;
            }

Here is the eqvivalent with alpha:

            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;
             }


来源:https://stackoverflow.com/questions/10250068/gaussian-blur-that-handles-alpha-transparency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!