Other Posts in Image Editing

  1. Perlin Noise
  2. Fault Formation
  3. Cellular Textures
  4. Resizing an Image in C#
  5. Box Blur and Gaussian Blur... Sort of...
  6. Thermal Erosion
  7. Using Mid Point Displacement to Create Cracks
  8. Fluvial Erosion
  9. Creating Marble Like Textures Procedurally
  10. Procedural Textures and Dilation
  11. Converting Image to Black and White in C#
  12. Getting an HTML Based Color Palette from an Image in C#
  13. Adding Noise/Jitter to an Image in C#
  14. Creating Pixelated Images in C#
  15. Edge detection in C#
  16. Using Sin to Get What You Want... In C#...
  17. Noise Reduction of an Image in C# using Median Filters
  18. Image Dilation in C#
  19. Sepia Tone in C#
  20. Kuwahara Filter in C#
  21. Matrix Convolution Filters in C#
  22. Symmetric Nearest Neighbor in C#
  23. Bump Map Creation Using C#
  24. Normal Map Creation Using C#
  25. Creating Negative Images using C#
  26. Red, Blue, and Green Filters in C#
  27. Converting an Image to ASCII Art in C#
  28. Adjusting Brightness of an Image in C#
  29. Adding Noise to an Image in C#
  30. Adjusting the Gamma of an Image Using C#
  31. Adjusting Contrast of an Image in C#
  32. Drawing a Box With Rounded Corners in C#
  33. Anding Two Images Together Using C#
  34. Motion Detection in C#
  35. Creating Thermometer Chart in C#
  36. Colorizing a Black and White Image in C#
  37. Extracting an Icon From a File
  38. Setting the Pixel Format and Image Format of an Image in .Net
  39. Using Unsafe Code for Faster Image Manipulation
  40. Sobel Edge Detection and Laplace Edge Detection in C#

Image Dilation in C#


This is probably not the most useful image manipulation function that you will ever see but it's fun (well if you're a programmer that enjoys screwing with people, it can be fun anyway). Anyway, image dilation is simply the taking of high intensity pixels (usually foreground pixels but not always) and grow the size of their boundaries. In other words we bleed out wards, causing bright colors to blur. It can be used for a number of effects, filling in of small spots in images, etc. For example, whenever you see a white screen (as though you're looking into direct bright light) and suddenly you see a dark blurry figure that slowly comes into focus, they're using this effect (in conjunction with a couple others).

The way this filter works is it takes a pixel (p0) and looks at a number of pixels around it (the shape of this can be anything but is usually a box around the center pixel). It then finds the pixel within that group with the highest intensity (in black and white images, the value closest to white and in color images you can break it down by red, green, and blue values) and changes the value of the pixel (p0) to that value. It does this for the entire image, causing the brighter values to bleed out.

Anyway, as always I wrote some code to accomplish this and figured I'd share:

   1: public static Bitmap Dilate(Bitmap Image, int Size)
   2: {
   3:     System.Drawing.Bitmap TempBitmap = Image;
   4:     System.Drawing.Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width, TempBitmap.Height);
   5:     System.Drawing.Graphics NewGraphics = System.Drawing.Graphics.FromImage(NewBitmap);
   6:     NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), System.Drawing.GraphicsUnit.Pixel);
   7:     NewGraphics.Dispose();
   8:     Random TempRandom = new Random();
   9:     int ApetureMin = -(Size / 2);
  10:     int ApetureMax = (Size / 2);
  11:     for (int x = 0; x < NewBitmap.Width; ++x)
  12:     {
  13:         for (int y = 0; y < NewBitmap.Height; ++y)
  14:         {
  15:             int RValue = 0;
  16:             int GValue = 0;
  17:             int BValue = 0;
  18:             for (int x2 = ApetureMin; x2 < ApetureMax; ++x2)
  19:             {
  20:                 int TempX = x + x2;
  21:                 if (TempX >= 0 && TempX < NewBitmap.Width)
  22:                 {
  23:                     for (int y2 = ApetureMin; y2 < ApetureMax; ++y2)
  24:                     {
  25:                         int TempY = y + y2;
  26:                         if (TempY >= 0 && TempY < NewBitmap.Height)
  27:                         {
  28:                             Color TempColor = TempBitmap.GetPixel(TempX, TempY);
  29:                             if (TempColor.R > RValue)
  30:                                 RValue = TempColor.R;
  31:                             if (TempColor.G > GValue)
  32:                                 GValue = TempColor.G;
  33:                             if (TempColor.B > BValue)
  34:                                 BValue = TempColor.B;
  35:                         }
  36:                     }
  37:                 }
  38:             }
  39:             Color TempPixel = Color.FromArgb(RValue, GValue, BValue);
  40:             NewBitmap.SetPixel(x, y, TempPixel);
  41:         }
  42:     }
  43:     return NewBitmap;
  44: }

The code above takes in an image and the size of the box (I haven't written code to take in a defined box structure but it can be changed to do so). It then returns a new Bitmap object with the dilation completed. Note that there is most likely an updated version within my utility library, so you may want to go and download it there.