I've found one cool algorithm for brightness and contrast's change.
public static bool Brightness(Bitmap b, int nBrightness)
{
if (nBrightness < -255 || nBrightness > 255)
return false;
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
int nVal = 0;
unsafe
{
byte \* p = (byte \*)(void \*)Scan0;
int nOffset = stride - b.Width\*3;
int nWidth = b.Width \* 3;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < nWidth; ++x )
{
nVal = (int) (p\[0\] + nBrightness);
if (nVal < 0) nVal = 0;
if (nVal > 255) nVal = 255;
p\[0\] = (byte)nVal;
++p;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
public static bool Contrast(Bitmap b, sbyte nContrast)
{
if (nContrast < -100) return false;
if (nContrast > 100) return false;
double pixel = 0, contrast = (100.0+nContrast)/100.0;
contrast \*= contrast;
int red, green, blue;
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte \* p = (byte \*)(void \*)Scan0;
int nOffset = stride - b.Width\*3;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < b.Width; ++x )
{
blue = p\[0\];
green = p\[1\];
red = p\[2\];
pixel = red/255.0;
pixel -= 0.5;
pixel \*= contrast;
pixel += 0.5;
pixel \*= 255;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
p\[2\] = (byte) pixel;
pixel = green/255.0;
pixel -= 0.5;
pixel \*= contrast;
pixel += 0.5;
pixel \*= 255;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
p\[1\] = (byte) pixel;
pixel = blue/255.0;
pixel -= 0.5;
pixel \*= contrast;
pixel += 0.5;
pixel \*= 255;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
p\[0\] = (byte) pixel;
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}