views:

1464

answers:

5

I have two bitmaps, produced by different variations of an algorithm. I'd like to create a third bitmap by subtracting one from the other to show the differences.

How can this be done in .NET? I've looked over the Graphics class and all its options, including the ImageAttributes class, and I have a hunch it involves the color matrix or remap tables functionality.

Does anyone have a link to some example code, or can point me in the right direction? A google search doesn't reveal much, unless my google-fu is failing me today.

+6  A: 

The real question is, what differences do you want to show? If you just need to operate on RGB color values, the best bet in my opinion is to just scan through both bitmaps and compare the Color values using GetPixel, and use SetPixel to generate your 'difference' bitmap. Perhaps you simply want to subtract the values and use those as the new Color value for the third bitmap. Or perhaps you want to calculate out the luminosity and use that. Even better, if you have three metrics for comparison, assign each one to the R G and B components of the color. I've used this approach for fractal colorization before.

There are other approaches, but with this one you are limited only to your imagination. It may not be the fastest approach, but it does not sound like performance is necessary for this scenario.

adzm
You're right, performance is not the nbr. 1 goal here, and the more I think about it, it sounds like I just need to write the code myself. I was initially thinking of a magic invert-image2-add-to-image1 algorithm, but how would it deal with negative results... ok, back to work then :)
Lasse V. Karlsen
If you do need the performance, remember that you can use the LockBits method of the Bitmap object to get a byte array of the raw pixel values, that you can operate on. Tends to be a lot faster than GetPixel and SetPixel.
driis
+1  A: 

Check out this project. It is a motion detector made by Andrew Kirillov. He implements a couple of filters to get the differences between two pictures and uses that to calculate movements. It is really nice done and its easy to modify and use in your own application.

http://www.codeproject.com/KB/audio-video/Motion_Detection.aspx

Stefan
A: 

First, define subtract ;-p What do you want the answer to look like?

The most performance way to do this is probably LockBits - it should be much quicker than lots of GetPixel calls, but you'll need to decode the bytes yourself. Easy if it is just something like 32bpp ARGB, but tricky for some more complex cases.

Marc Gravell
A: 

I've read somewhere that the language used in Adobe Pixel Bender is inspired by something that Microsoft once did. Don't remember where I read it. My thinking is that maybe that Microsoft "something" is wrapped into something that a .Net project can use. Overkill for just subtracting two images, but anyway.

PEZ
+1  A: 

This can be done by PInvoking the BitBlt API function. Here is some sample code:

http://www.codeproject.com/KB/GDI-plus/Bitblt_wrapper_class.aspx

The sample uses the SRCCOPY raster op code; to get the differences between two bitmaps, you'd instead want to use SRCPAINT or something (GOOGLE should give the list of codes).

GetPixel and SetPixel (on the Bitmap class) are unbelievably slow. Using LockBits will be much faster, but you'll still have to write your own code.

Update: this is a better link:

http://www.pinvoke.net/default.aspx/gdi32.BitBlt

and includes all the possible ternary raster operations (SRCPAINT or SRCAND are probably what you're looking for.).

MusiGenesis