How to manipulate images at the pixel level in C#

Solution 1:

If you want speed, then LockBits. See here for a good walkthrough by Bob Powell. If you just want to edit a few, then GetPixel/SetPixel should do what you want.

Solution 2:

A sample code routine (I use this for simple merge and compare functionality. It takes two images and produces a third greyscale image showing the differences between the two images as a greyscale tone level. The darker it is, the more the diff.):

    public static Bitmap Diff(Bitmap src1, Bitmap src2, int x1, int y1, int x2, int y2, int width, int height)
{
    Bitmap diffBM = new Bitmap(width, height, PixelFormat.Format24bppRgb);

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            //Get Both Colours at the pixel point
            Color col1 = src1.GetPixel(x1 + x, y1 + y);
            Color col2 = src2.GetPixel(x2 + x, y2 + y);

            // Get the difference RGB
            int r = 0, g = 0, b = 0;
            r = Math.Abs(col1.R - col2.R);
            g = Math.Abs(col1.G - col2.G);
            b = Math.Abs(col1.B - col2.B);

            // Invert the difference average
            int dif = 255 - ((r+g+b) / 3);

            // Create new grayscale RGB colour
            Color newcol = Color.FromArgb(dif, dif, dif);

            diffBM.SetPixel(x, y, newcol);

        }
    }

    return diffBM;
}

Marc's post notes LockBits and using that to modify the image directly in memory. I would suggest looking at that rather than what I have posted if performance is a concern. Thanks Marc!

Solution 3:

System.Drawing.Bitmap has a GetPixel(int x, int y) public method that returns a System.Drawing.Color structure. That struct has byte members R, G, B, and A, which you can modify directly, and then call SetPixel(Color) on your Bitmap again.
Unfortunately, that's going to be relatively slow, but it's by the easiest way to do it in C#. If you are working with individual pixels a lot and find the performance is lacking, and you need something faster, you can use LockBits... It's a lot more complicated though, as you need to understand the bit structure for that color depth and type, and work with the bitmap's stride and what not... so if you find it's necessary, make sure you find a good tutorial! There are several out there on the web, Googling "C# LockBits" will get you a half dozen that are worth a read.

Solution 4:

If performance is critical, another alternative to LockBits is managed DirectX.

See the earlier Stack Overflow question Rendering graphics in C# for more information.

Like Lockbits you will need to use the unsafe keyword/compiler switch, but you get high performance pixel level access.

You also get higher performance screen rendering via DirectX backbuffering, when compared with using the normal Bitmap class and PictureBox control.