12,395,871 members (62,979 online)
alternative version

91.8K views
46 bookmarked
Posted

# Gausian and Alpha Blurring

, 22 Feb 2004
 Rate this:
Step by step instructions and theory

## Introduction

I created this as a part of my icon builder project. Let me back up a sec and explain. In my icon project I deal extensively with icons. A problem creeps up when the user resizes a lowres icon to a larger size. What ends up happening is edges of the icon get frayed. My objective here was to write something to un fray the edges. Ok fast forward a bit

I was contemplating how to accomplish my goal when I though "What I need here is a gausian blur function". Unfortunately, there is nothing like this in the standard GDI+ functions. So (yet again) I decided to roll my own solution of creating a gausian blur (like) function. The reason it isn't exactly the same as the real mccoy is it doesn't take into account a transform matrix, so as a result the colors all have the same weighted values (but you can't really tell a difference).

## Demystifying the "Image"

Image stuff has always made me step back and say ouch. Until you really think about it, it can seem like a really complex issue when in reality it is no harder then that address book program everyone wrote in school (Many eon's ago, in pascal). I will try to break this concept down and reduce it to bear bones for you.

If nothing else remember this:
An image is just a 2D array of colors, and we "could" represent an image in an array, like so:

```For PixelX = 0 To Image.Width - 1
For PixelY = 0 To Image.Height - 1
ImagePixel(PixelX, PixelY) = Image.getpixel(PixelX, PixelY)
Next
Next
```
This will loop picture and create an array of colors for the entire image (luckily we don't have to do this, I am just trying to make a point). An image is nothing more then an array of colors that we can modify.

## Blurring the line

What happens when we take red and add green to it? (we get yellow) What happens when we take the same concept and apply it to a 2D array? (we get a blur effect). In the last sample snipit of code we learned that GetPixel returns the color of a point in an image. So consider this:

```For PixelX = 0 To Image.Width - 2
For PixelY = 0 To Image.Height - 2
Dim Color1 As Color = Image.getpixel(PixelX, PixelY)
Dim Color2 As Color = Image.getpixel(PixelX + 1, PixelY)
Dim Merge As Color = Color.FromArgb( _
(Color1.A + Color2.A) / 2, _
(Color1.R + Color2.R) / 2, _
(Color1.G + Color2.G) / 2, _
(Color1.B + Color2.B) / 2)
SetPixel(PixelX, PixelY, Merge)

Next
Next
```

Each color (for our purposes here) is made up of four values A = Alpha, R = Red, G = Green, B = Blue. So in essence what we are doing is taking these "color channels" and averaging them with the next pixel. So lets say pixel (1, 1) is red and pixel (2, 1) is green, we mix then and set pixel (1, 1) to the resulting color, yellow. Congrats, you just made a blur! Actually it resembles more of a streak.

## Building a better blur

Instead of blurring two pixels lets take a greater sampling and average a 3X3 group of pixels, this will give you a better blur effect. The first thing we need to do is have a function that weeds out those pesky pixels that don't exist. As I have demonstrated above the 3X3 sample of pixels for (1,1) will render five points that don't exist.

```dim pixels as new arraylist
dim x as integer, y as integer
dim size as new size(3, 3)
dim imageSize as new size(10, 10)

For x = PixelX - CInt(Size.Width / 2) To PixelX + _
CInt(Size.Width / 2)
For y = Pixely - CInt(Size.Height / 2) To Pixely + _
CInt(Size.Height / 2)
If (x > 0 And x < imageSize.Width) And _
(y > 0 And y < imageSize.Height) Then
End If
Next
Next
```

What this little gem does is take PixelX and PixelY (1, 1 in this case) and create an array of the pixel colors. This array of pixel colors will contain the color information for four pixels (1,1) (2,1) (1,2) and (2,2). Here are two more examples:

Example one (2,1) will yeild 6 points. Example 2 will yield 9 points.

As you can see this is a multi-purpose function that will return up to nine pixels color, depending on where the pixel is located.
Now that we have an array of the pixels to use in this blur lets see how we can average them together.

```Dim thisColor As Color

Dim alpha As Integer = 0
Dim red As Integer = 0
Dim green As Integer = 0
Dim blue As Integer = 0

For Each thisColor In pixels
alpha += thisColor.A
red += thisColor.R
green += thisColor.G
blue += thisColor.B
Next

Return Color.FromArgb(alpha / pixels.Count, _
red / pixels.Count, _
green / pixels.Count, _
blue / pixels.Count)
```

This will loop the collection of pixels adding up the color channels as it goes along. Then when its done it will return a color with the averages of all the colors, This resulting color is what you set that pixel (1, 1) to.

## What is an alpha channel

An alpha channel is a color channel that represents the transparency of that color. In the above all three squares are red but the alpha channels are different. The first square is solid and the alpha channel is set to 255. The second square is 50% solid or (127.5) and the last square is completely transparent with an alpha of 0% or (0).

Alpha channels are used most commonly in GIF, PNG and ICO files. For this reason you can load up a transparent gif and check the alpha channel of every pixel and get an outline of the solid parts of the image.

## Alpha Blur

Using the same technique as before we can test to see if the pixel is not solid and send it to our blur function thus blurring the alpha channels or edges of the object.
Note
the object must be transparent for this to work!

## Putting it all together

Here is a full example of the program I built that does this gausianesk blurring.

```Private Function Average(ByVal Size As Size, ByVal imageSize As SizeF, _
ByVal PixelX As Integer, ByVal Pixely As Integer) As Color

Dim pixels As New ArrayList
Dim x As Integer, y As Integer
Dim bmp As Bitmap = PictureBox1.Image.Clone

' Find the color for each pixel and add it to a new array.
'
' Remember a 5X5 area on or near the edge will ask
' for pixels that don't
' exist in our image, this will filter those out.
'
For x = PixelX - CInt(Size.Width / 2) To PixelX + _
CInt(Size.Width / 2)
For y = Pixely - CInt(Size.Height / 2) To Pixely + _
CInt(Size.Height / 2)
If (x > 0 And x < imageSize.Width) And _
(y > 0 And y < imageSize.Height) Then
End If
Next
Next

' Adverage the A, R, G, B channels
' reflected in the array

Dim thisColor As Color
Dim alpha As Integer = 0
Dim red As Integer = 0
Dim green As Integer = 0
Dim blue As Integer = 0

For Each thisColor In pixels
alpha += thisColor.A
red += thisColor.R
green += thisColor.G
blue += thisColor.B
Next

' Return the sum of the colors / the number of colors (The average)
'
Return Color.FromArgb(alpha / pixels.Count, _
red / pixels.Count, _
green / pixels.Count, _
blue / pixels.Count)
End Function

Private Sub gausianBlur(ByVal alphaEdgesOnly As Boolean, _
ByVal blurSize As Size)

Dim PixelY As Integer
Dim PixelX As Integer
Dim bmp As Bitmap = PictureBox1.Image.Clone

' UI Stuff
Label1.Text = "Applying Gausian Blur of " & blurSize.ToString

Progress.Maximum = bmp.Height * bmp.Width
Progress.Minimum = 0
Progress.Value = 0

' Loop the rows of the image
For PixelY = 0 To bmp.Width - 1

' Loop the cols of the image
For PixelX = 0 To bmp.Height - 1
If Not alphaEdgesOnly Then     ' Blur everything
bmp.SetPixel(PixelX, PixelY, Average(blurSize, _
bmp.PhysicalDimension, PixelX, PixelY))
ElseIf bmp.GetPixel(PixelX, PixelY).A _
<> 255 Then  ' Alpha blur channel check
bmp.SetPixel(PixelX, PixelY, Average(blurSize, _
bmp.PhysicalDimension, PixelX, PixelY))
End If
Progress.Value += 1
Application.DoEvents()
Next
Next

PictureBox1.Image = bmp.Clone
bmp.Dispose()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
gausianBlur(False, New Size(6, 6))
End Sub
```

It looks kind of mind numbing at first until you break it down like I have just done for you. Basically when you click `button1` it sends the information to the `gausianBlur `sub to build the blur. The `gausianBlur` sub checks if that part of the image needs to be blurred and if it does sets that pixel to the output color of the `adverage` function.

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

## About the Author

 Web Developer United States
I started programming for fun when I was about 10 on an Franklin Ace 1000.

I still do it just for fun but it has gotten me a few jobs over the years. More then I can say for my Microsoft Certifications.

The way I learned was by example, now its time to give back to the next generation of coders.

## Comments and Discussions

 First Prev Next
 thanks Hooman_Kh10-Aug-15 15:24 Hooman_Kh 10-Aug-15 15:24
 My vote of 3 i008-Dec-11 13:36 i00 8-Dec-11 13:36
 Faster in C# Christian Graus7-Apr-05 13:13 Christian Graus 7-Apr-05 13:13
 Re: Faster in C# Skeletron_X20-Mar-07 14:39 Skeletron_X 20-Mar-07 14:39
 Re: Faster in C# benedekfi11-Mar-10 3:30 benedekfi 11-Mar-10 3:30
 Re: NOT Faster in C# i008-Dec-11 12:26 i00 8-Dec-11 12:26
 X,Y switch magnellfan2-Apr-05 21:24 magnellfan 2-Apr-05 21:24
 Little Typo rifx12-Mar-04 12:44 rifx 12-Mar-04 12:44
 Re: Little Typo Matthew Hazlett12-Mar-04 14:39 Matthew Hazlett 12-Mar-04 14:39
 Misleading title Anonymous2-Mar-04 7:16 Anonymous 2-Mar-04 7:16
 Re: Misleading title Matthew Hazlett2-Mar-04 8:37 Matthew Hazlett 2-Mar-04 8:37
 Last Visit: 31-Dec-99 18:00     Last Update: 24-Jul-16 5:27 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.