Search code examples
c#bitmapdifferentiation

Fast way of calculating differences between two bitmaps


Possible Duplicate:
What is the fastest way I can compare two equal-size bitmaps to determine whether they are identical?

I'm trying to efficiently calculate the differences between two bitmaps and set any matching pixels black. I've tried this:

for (int x = 0; x < 1280; x++)
{
    for (int y = 0; y < 720; y++)
    {
        if (bitmap.GetPixel(x, y) == bitmap2.GetPixel(x, y))
        {
            bitmap2.SetPixel(x, y, Color.Black);
        }
    }
}

But it turns out that GetPixel and SetPixel are slow so this doesn't really work well enough. Anyone know an alternative (faster) way of doing this?


Solution

  • This method uses unsafe code, assuming bitmaps are the same size and are 4 bytes per pixel.

    Rectangle bounds = new Rectangle(0,0,bitmapA.Width,bitmapA.Height);
    var bmpDataA = bitmapA.LockBits(bounds, ImageLockMode.ReadWrite, bitmapA.PixelFormat);
    var bmpDataB = bitmapB.LockBits(bounds, ImageLockMode.ReadWrite, bitmapB.PixelFormat);
    
    const int height = 720;
    int npixels = height * bmpDataA.Stride/4;
    unsafe {
        int * pPixelsA = (int*)bmpDataA.Scan0.ToPointer();
        int * pPixelsB = (int*)bmpDataB.Scan0.ToPointer();
    
        for ( int i = 0; i < npixels; ++i ) {
            if (pPixelsA[i] != pPixelsB[i]) {
                 pPixelsB[i] = Color.Black.ToArgb();
            }
        }
    }
    bitmapA.UnlockBits(bmpDataA);
    bitmapB.UnlockBits(bmpDataB);
    

    For a safe method, copy the pixel data to an array buffer for processing using the InteropServices.Marshal.Copy methods.