Unsafe in C# and Image Processing
// August 15th, 2009 // Programming
From my last projects, I write many custom class to manipulating image. Today I will share basic code to write C# code when you focusing on Image Processing.
When I use Bitmap function GetPixel and SetPixel, oh.. .NET is bad for Image Processing.. and that’s not 100% right. We still have pointers on C# like on C++. To use it just go to Project->Properties->Build than check “Allow unsafe code”.
Now, go ahead and try to understand how to use unsafe code in C# and implement it on Image Processing.
First thing is get image from file :
Bitmap bmp = (Bitmap)Image.FromFile("image.jpg");
Than lock that bitmap, The public functions in the class that locks and unlocks the specified area of the image into the memory. The paramenters of the LockBits function are, a Rectangle object specifying the area to be Locked, then 2 integers specifying the access level for the object and the other showing the format of the image. This is done through two enumirations like ImageLockMode, and PixelFormat. They are narrated after this class. The LockBits returns the object of the BitmapData class and UnLockBits takes the object of the BitmapData class.
//Lock bitmap BitmapData imageData = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
The pixel format defines the number of bits of memory associated with one pixel of data. In other words the format defines the order of the color components within a single pixel of data. Normaly, PixelFormat.Format24bppRgb is used. PixelFormat.Format24bppRgb specifies that the format is 24 bits per pixel; 8 bits each are used for the red, green, and blue components. In the 24 bit format image, the image consists of pixels consisting of 3 bytes, one for each red, green, and blue. The first byte in the image contains the blue color, the second byte contains the green color, and the third byte contains the red color of the pixel, and they form the color
of the specified pixel.
//Pixel size from right most line to next down first line int offset = imageData.Stride - imageData.Width * 3;
Now here the unsafe block code
unsafe
{
//Go to first pixel
byte* p = (byte*)imageData.Scan0.ToPointer();
//For each line
for (int y = 0; y < bmp.Height; y++)
{
//For Each Pixel (bmp.Width * 3) because jpg has R, G, and B value
for (int x = 0; x < bmp.Width * 3; x++)
{
//Make invert from original image
*p = (byte)(255 - *p);
//Go to next pointer
p++;
}
//move pointer right most line to next down first line
//skip the unused space
p += offset;
}
}
After that call UnlockBits
//Call UnlockBits function bmp.UnlockBits(imageData);
Here my full code :
private void btnLoad_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialogImage = new OpenFileDialog();
openFileDialogImage.Filter = "JPEG Image|*.jpg;";
if (openFileDialogImage.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
//original image
Bitmap original = (Bitmap)Image.FromFile(openFileDialogImage.FileName);
pictureBox1.Image = original;
//Image to manipulate
Bitmap bmp = (Bitmap)Image.FromFile(openFileDialogImage.FileName);
//Lock bitmap
BitmapData imageData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
//Pixel size from right most line to next down first line
int offset = imageData.Stride - imageData.Width * 3;
unsafe
{
//Go to first pixel
byte* p = (byte*)imageData.Scan0.ToPointer();
//For Each Line
for (int y = 0; y < bmp.Height; y++)
{
//For Each Pixel (bmp.Width * 3) because jpg has R, G, and B value
for (int x = 0; x < bmp.Width * 3; x++)
{
//Make invert from original image
*p = (byte)(255 - *p);
p++;
}
p += offset;
}
}
//Unlock data
bmp.UnlockBits(imageData);
//Set it to picture box
pictureBox2.Image = bmp;
}
}
Here result of both image :

By : Willy Achmat Fauzi




TL;DR; but you have great pictures.
Sent via Blackberry