简体   繁体   中英

How to subtract one bitmap from another in C#/.NET?

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.

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 RG 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.

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

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.).

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM