I made a convolution testing program for experimenting with stuff. I've created a 5x5 Gaussian kernel for blurring. Everything looked fine, then I tried to blur a transparent png with a white circle in the middle. On the blurred image, the edge looks like a gradient from white to black. This is mathematically correct, because the transparent points are treated as black, transparent pixels, so the convolution should gradually give darker colors near the edge. But if I do a gaussian blur on the same image e.g. in GIMP, the circle will be fully white, with gradually more transparency toward the edges. I'd like to get this effect. What am I missing?

If I set the transparent pixels to transparent white, it'll work, but only if the blurred color is white.

This is the original image: The original image

This is the result I get if I left the transparent pixels on default: Blur on the original

And if I set the transparent pixels to #00FFFFFF, I'll get this (this is the intended IF the blurred color is white)

Intended result


I apologise for only skimming through your question/answer and the links you gave but I thought it would be a good idea to post what needs to be done to correctly do any blending and/or filtering on images with an alpha channel.

The first thing to note is that all calculations should be done in a linear colour space, but the image data in PNGs and JPEGs is most likely to be in sRGB which is non-linear. You should convert this data to a linear form before doing any calculations. For example, the average of black (0,0,0) and white (255,255,255) in sRGB is not (127,127,127) but (off the top of my head) something like (186,186,186). The filtering of images, especially those with neighbouring, complementary, saturated colours (e.g. Yellow&Blue), can look quite odd if you don't take gamma into account.

The second part of this theory dates back to Porter and Duff's seminal 1984 paper, "Compositing Digital Images", which introduces the concept of pre-multiplied alpha. Pre-multiplied alpha basically means that you multiply the RGBs by the alpha value before doing calculations.

The Porter-Duff paper states...

There are a few reasons to dismiss this proposal, the most severe being that all compositing operations will involve multiplying the 1 in the red channel by the .5 in the alpha channel to compute the red contribution of this object at this pixel. The desire to avoid this multiplication points up a better solution, storing the pre-multiplied value in the color component, so that (.5,0,0,.5) will indicate a full red object half covering a pixel.

... which suggests this was initially done just to reduce computation costs, but in Jim Blinn's article "Compositing-Theory", he demonstrates that the correct way to do any filtering or compositing operations is to first convert everything to premultipled.

Once you have linearised and then pre-multiplied your pixel data, do the filtering/blending and, finally, undo the pre-multiply and reapply the gamma function to map back to sRGB.


As it turned out, I forgot to weight the color channel by the transparency, so I got the same issue as written here: Blur Transparency Bug


How do you load your image?

Maybe your image is loaded as RGB instead of RGB-A, which means you are totally ignoring Alpha channel (the transparency value). In this case the transparent pixels are converted into black ones.

If you are using OpenCV library, this article might help you load the image with 4-channels (into a 4-dimensional array); then you are able to apply Gaussian-blur function on every 4 channels and get the desired result.

  • $\begingroup$ The image is loaded with Java's ImageIO.read, and it'll correctly load the transparency. I've attached pictures. $\endgroup$
    – Rothens
    Aug 19 '17 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.