Thursday, March 13, 2008

Applying Gamma correction to an Image

Recently, one of my tasks was to apply non-linear gamma correction to JPEG image. Using .NET Framework 2.0 System.Drawing.Imaging library one can reach this target quickly, however there is one big notice about working with JPEGs: Never do any transformations with JPEG images, first confert them to 32 bit Argb! If you pbey this, you may catch System.OutOfMemoryException. Also I was found in one post (can't find that link... :( ) that this format is also most efficient in terms of performance...


public static Bitmap CorrectGamma(Image source, decimal gamma)
{
Bitmap intermediate = new Bitmap(source.Width, source.Height, PixelFormat.Format32bppPArgb);

// Create an ImageAttributes object and set the gamma
ImageAttributes imageAttr = new ImageAttributes();
imageAttr.SetGamma(Convert.ToSingle(gamma));

Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
using (Graphics g = Graphics.FromImage(intermediate))
{
g.DrawImage(source, rect, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel);
}

Bitmap corrected = new Bitmap(source.Width, source.Height, PixelFormat.Format32bppPArgb);
using (Graphics g = Graphics.FromImage(corrected))
{
g.DrawImage(intermediate, rect, 0, 0, intermediate.Width, intermediate.Height, GraphicsUnit.Pixel, imageAttr);
}

intermediate.Dispose();
return corrected;

}



It is essential that image is transformed once from JPEG to Format32bppPArgb (I described this in another post) and only after that it is transfomed second time, applying ImageAttributes. Doing both at one time will cause OutOfMemoryException, but of course you can try this out for yourself :)

No comments: