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#

Adjusting Contrast of an Image in C#

5/1/2009

Ok, so earlier I talked about adjusting the brightness and the gamma of an image. So in this post I'm going to show you how to adjust the contrast of an image. Contrast deals with the visual properties that allows us to see two seperate objects as well as the background. We can measure the contrast of something by taking into account both the color and brightness. In otherwords if I have a green box inside of a green circle, there's basically no contrast. If you have a red box inside a blue circle, there is a higher contrast. So how do we go about and adjust the contrast

   1: /// <summary>
   2: /// Adjusts the Contrast
   3: /// </summary>
   4: /// <param name="OriginalImage">Image to change</param>
   5: /// <param name="Value">Used to set the contrast (-100 to 100)</param>
   6: /// <returns>A bitmap object</returns>
   7: public static Bitmap AdjustContrast(Bitmap OriginalImage, float Value)
   8: {
   9:     Bitmap NewBitmap = new Bitmap(OriginalImage.Width, OriginalImage.Height);
  10:     BitmapData NewData = Image.LockImage(NewBitmap);
  11:     BitmapData OldData = Image.LockImage(OriginalImage);
  12:     int NewPixelSize = Image.GetPixelSize(NewData);
  13:     int OldPixelSize = Image.GetPixelSize(OldData);
  14:     Value = (100.0f + Value) / 100.0f;
  15:     Value *= Value;
  16:  
  17:     for (int x = 0; x < NewBitmap.Width; ++x)
  18:     {
  19:         for (int y = 0; y < NewBitmap.Height; ++y)
  20:         {
  21:             Color Pixel = Image.GetPixel(OldData, x, y, OldPixelSize);
  22:             float Red = Pixel.R / 255.0f;
  23:             float Green = Pixel.G / 255.0f;
  24:             float Blue = Pixel.B / 255.0f;
  25:             Red = (((Red - 0.5f) * Value) + 0.5f) * 255.0f;
  26:             Green = (((Green - 0.5f) * Value) + 0.5f) * 255.0f;
  27:             Blue = (((Blue - 0.5f) * Value) + 0.5f) * 255.0f;
  28:             Image.SetPixel(NewData, x, y,
  29:                 Color.FromArgb(MathHelper.Clamp((int)Red, 255, 0),
  30:                 MathHelper.Clamp((int)Green, 255, 0),
  31:                 MathHelper.Clamp((int)Blue, 255, 0)),
  32:                 NewPixelSize);
  33:         }
  34:     }
  35:     Image.UnlockImage(NewBitmap, NewData);
  36:     Image.UnlockImage(OriginalImage, OldData);
  37:     return NewBitmap;
  38: }

Note that the code above uses a couple of functions from my utility library, specifically Image.LockImage, UnlockImage, etc. to speed things up a bit. Those functions can be removed or replaced with the built in GetPixel/SetPixel functions. Anyway, if you take a look at the code, you'll notice that I start by normalizing the values from 0.0 to 1.0 (with Value ending up going from 0 to 4 once normalized). Once a pixel is normalized, we multiply it by the value and then convert it back to the 0 to 255 range. That's pretty much it. The function takes in a bitmap and a value between -100 and 100 (you can use a different range but that will work the best) with a higher number causing more contrast and negative numbers decreasing it. Anyway, definitely try it out, leave feedback, and happy coding.



Comments

Roey
March 12, 2012 2:32 AM
It is better to use ColorMatrix and draw the image on a new surface.It's faster, and give some nice extra options.

James Craig
June 28, 2010 10:36 AM

Most of the code on my website is to show the concept and not meant for speed. Most likely in the future I will revisit my various image manipulation posts and give a more advanced version that uses LockBits. That being said, thank you for the offer.

Tom
June 28, 2010 9:49 AM

I've modified this routine for my own use. I've implemented Bitmap.LockBits, which really speeds things up. If you want to update your post, email me for the source.