Click here to Skip to main content
15,880,608 members
Articles / Mobile Apps / Windows Mobile
Article

Gausian and Alpha Blurring

Rate me:
Please Sign up or sign in to vote.
4.43/5 (22 votes)
22 Feb 20045 min read 121K   3.5K   49   11
Step by step instructions and theory

Sample Image - screenshot.png

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:

VB.NET
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:

VB.NET
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.

VB.NET
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
            pixels.Add(bmp.GetPixel(x, y))
        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.

VB.NET
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.

VB.NET
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
                pixels.Add(bmp.GetPixel(x, y))
            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.

License

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


Written By
Web Developer
United States 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. Smile | :)

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



Comments and Discussions

 
Generalthanks Pin
Hooman_Kh10-Aug-15 15:24
Hooman_Kh10-Aug-15 15:24 
GeneralMy vote of 3 Pin
i008-Dec-11 13:36
i008-Dec-11 13:36 
GeneralFaster in C# Pin
Christian Graus7-Apr-05 13:13
protectorChristian Graus7-Apr-05 13:13 
GeneralRe: Faster in C# Pin
Skeletron_X20-Mar-07 14:39
Skeletron_X20-Mar-07 14:39 
GeneralRe: Faster in C# Pin
benedekfi11-Mar-10 3:30
benedekfi11-Mar-10 3:30 
GeneralRe: NOT Faster in C# Pin
i008-Dec-11 12:26
i008-Dec-11 12:26 
GeneralX,Y switch Pin
magnellfan2-Apr-05 21:24
magnellfan2-Apr-05 21:24 
GeneralLittle Typo Pin
rifx12-Mar-04 12:44
rifx12-Mar-04 12:44 
GeneralRe: Little Typo Pin
Matthew Hazlett12-Mar-04 14:39
Matthew Hazlett12-Mar-04 14:39 
GeneralMisleading title Pin
Anonymous2-Mar-04 7:16
Anonymous2-Mar-04 7:16 
GeneralRe: Misleading title Pin
Matthew Hazlett2-Mar-04 8:37
Matthew Hazlett2-Mar-04 8:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

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