can somebody explain me this code for contrast of image.
public Bitmap contrast(Bitmap b, sbyte nContrast)
{
if (nContrast < -100) return b;
if (nContrast > 100) return b;
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 b; ;
}
Loading

Vladimir NaniPosted Apr 17, 2010, 5:32 AM
public Bitmap contrast(Bitmap b, sbyte nContrast)
You can`t change contrast of image by more 100
if (nContrast < -100) return b;
if (nContrast > 100) return b;
Declare some var pixel and contrast which range now is [0,2]
double pixel = 0, contrast = (100.0 + nContrast) / 100.0;
Loads data from Bitmap in memory Rectangle specifies the region of bits to lock, you can read and write bits info,
format specifies that there is 24 bits per pixel and RGB color format.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
You scan your images with lines.
Stride prop means actual bytes consumed by one line
and it may differ from width of your picture multiplied by 3(RGB means 3 bytes per each color)
int stride = bmData.Stride;
IntPtr is a struct that presenting a pointer.
In our case it points to memory location that has ours pictures pixels array.
Scan0 returns a first pixel.
System.IntPtr Scan0 = bmData.Scan0;
Because you are using pointers you must block your code in unsafe{}
Casting to byte*;
byte* p = (byte*)(void*)Scan0;
Next line shows difference between our Width prop in bytes and actual bytes of a scan line;
int nOffset = stride - b.Width * 3;
Looping in pixel matrix.
for (int y = 0; y < b.Height; ++y)
{
for (int x = 0; x < b.Width; ++x)
{
Because in memory we have BGR, first byte of current pixel shows blue color and so on.
blue = p[0];
green = p[1];
red = p[2];
We change our pixels red canal depending on contrast amount.
pixel = red / 255.0;
pixel -= 0.5;
pixel *= contrast;
pixel += 0.5;
pixel *= 255;
Looking if there is overflow.
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
Casting double value to byte and writing in memory.
p[2] = (byte)pixel;
Respectively for blue and green...
Shifting our pointer with three bytes means looking to next pixel.
p += 3;
After one scan line loop shifting pointer with offset calculated previously.
p += nOffset;
After we done we unlock our bits from memory and returning reference to changed bitmap
b.UnlockBits(bmData);
return b;