Adjusting Contrast of an Image in C#

Contrast correction of an image.
May 01 2009 by James Craig

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:

 /// <summary>
/// Adjusts the Contrast
/// </summary>
/// <param name="OriginalImage">Image to change</param>
/// <param name="Value">Used to set the contrast (-100 to 100)</param>
/// <returns>A bitmap object</returns>
public static Bitmap AdjustContrast(Bitmap OriginalImage, float Value)
{
Bitmap NewBitmap = new Bitmap(OriginalImage.Width, OriginalImage.Height);
BitmapData NewData = Image.LockImage(NewBitmap);
BitmapData OldData = Image.LockImage(OriginalImage);
int NewPixelSize = Image.GetPixelSize(NewData);
int OldPixelSize = Image.GetPixelSize(OldData);
Value = (100.0f + Value) / 100.0f;
Value \*= Value;

for (int x = 0; x < NewBitmap.Width; ++x)
{
for (int y = 0; y < NewBitmap.Height; ++y)
{
Color Pixel = Image.GetPixel(OldData, x, y, OldPixelSize);
float Red = Pixel.R / 255.0f;
float Green = Pixel.G / 255.0f;
float Blue = Pixel.B / 255.0f;
Red = (((Red - 0.5f) \* Value) + 0.5f) \* 255.0f;
Green = (((Green - 0.5f) \* Value) + 0.5f) \* 255.0f;
Blue = (((Blue - 0.5f) \* Value) + 0.5f) \* 255.0f;
Image.SetPixel(NewData, x, y,
Color.FromArgb(MathHelper.Clamp((int)Red, 255, 0),
MathHelper.Clamp((int)Green, 255, 0),
MathHelper.Clamp((int)Blue, 255, 0)),
NewPixelSize);
}
}
Image.UnlockImage(NewBitmap, NewData);
Image.UnlockImage(OriginalImage, OldData);
return NewBitmap;
}

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.