<p>As it turned out, I forgot to weight the color channel by the transparency, so I got the same issue as written here:
<a href="http://www.imagemagick.org/Usage/bugs/blur_trans/" rel="nofollow noreferrer">Blur Transparency Bug</a></p>

CC BY-SA 3.0
2017-08-19T11:55:10.607Z
2017-08-19T11:55:10.607Z
Rothens
<p>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 <em>correctly</em> do any blending and/or filtering on images with an alpha channel.</p>
<p>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 <a href="https://en.wikipedia.org/wiki/SRGB" rel="nofollow noreferrer">sRGB</a> 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&amp;Blue), can look quite odd if you don't take gamma into account.</p>
<p>The second part of this theory dates back to Porter and Duff's seminal 1984 paper, &quot;<a href="https://keithp.com/%7Ekeithp/porterduff/p253-porter.pdf" rel="nofollow noreferrer">Compositing Digital Images</a>&quot;, 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.</p>
<p>The Porter-Duff paper states...</p>
<blockquote>
<p>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.</p>
</blockquote>
<p>... which suggests this was initially done just to reduce computation costs, but in Jim Blinn's article <a href="https://graphics.stanford.edu/courses/cs248-02/blinn_theory.pdf" rel="nofollow noreferrer">&quot;Compositing-Theory&quot;</a>, he demonstrates that the correct way to do any filtering or compositing operations is to first convert everything to premultipled.</p>
<p>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.</p>

CC BY-SA 4.0
2017-08-21T16:27:25.710Z
2020-08-03T08:44:17.107Z
2020-08-03T08:44:17.107Z
Simon F
<p>How do you load your image?</p>

<p>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.</p>

<p>If you are using OpenCV library, <a href="https://stackoverflow.com/questions/3803888/opencv-how-to-load-png-images-with-4-channels">this article</a> 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.</p>

CC BY-SA 3.0
2017-08-19T11:46:28.083Z
The image is loaded with Java's ImageIO.read, and it'll correctly load the transparency. I've attached pictures.
Rothens
CC BY-SA 3.0
2017-08-19T11:27:04.580Z
2017-08-19T11:27:04.580Z
Aref
<p>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?</p>

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

<p>This is the original image:
<a href="https://i.sstatic.net/v6Tdw.png" rel="noreferrer"><img src="https://i.sstatic.net/v6Tdw.png" alt="The original image"></a></p>

<p>This is the result I get if I left the transparent pixels on default:
<a href="https://i.sstatic.net/u00CV.png" rel="noreferrer"><img src="https://i.sstatic.net/u00CV.png" alt="Blur on the original"></a></p>

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

<p><a href="https://i.sstatic.net/BfVw8.png" rel="noreferrer"><img src="https://i.sstatic.net/BfVw8.png" alt="Intended result"></a></p>

<texture>
Gaussian blur with transparency
Rothens
# Gaussian blur with transparency

(Asked by: username_0 on 2017-08-19)

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](https://i.sstatic.net/v6Tdw.png)](https://i.sstatic.net/v6Tdw.png)

This is the result I get if I left the transparent pixels on default:
[![Blur on the original](https://i.sstatic.net/u00CV.png)](https://i.sstatic.net/u00CV.png)

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](https://i.sstatic.net/BfVw8.png)](https://i.sstatic.net/BfVw8.png)

**Tags:** texture


---

## 3 answers

### Answer by username_0 on 2017-08-19. Score: 3 | Accepted answer

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](http://www.imagemagick.org/Usage/bugs/blur_trans/)


---

### Answer by username_1 on 2017-08-21. Score: 7

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](https://en.wikipedia.org/wiki/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](https://keithp.com/%7Ekeithp/porterduff/p253-porter.pdf)", 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"](https://graphics.stanford.edu/courses/cs248-02/blinn_theory.pdf), 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.


---

### Answer by username_2 on 2017-08-19. Score: 1

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](https://stackoverflow.com/questions/3803888/opencv-how-to-load-png-images-with-4-channels) 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.

> **Comments:**
> **username_0**: The image is loaded with Java's ImageIO.read, and it'll correctly load the transparency. I've attached pictures.  

---

