Click to See Complete Forum and Search --> : Converting a color bitmap do grayscale using GDI


Orf
May 2nd, 2006, 12:32 PM
Hi everyone.
I store RGB frames coming from a frame grabber in memory, then I process the frame to detect movement and similar things. I need to work on grayscale rames, but they arrive in RGB 24 bit form. I perform the conversion when I fetch the frame, "manually" - that is, (R+G+B)/3.
Now I'd like to let GDI do this stuff for me. I'd like to create a grayscale memory DC, draw my frame there using StretchDIBits (I also needto decrease the resolution at will) then get the new buffer with GetDIBits.
Does the whole thing make sense? (It seems so to me...)
How can I get there?
Thanks.
Ciao.

Mike Harnad
May 2nd, 2006, 01:36 PM
Take a look at CreateGrayscaleIcon() (http://www.codeguru.com/cpp/g-m/bitmap/icons/article.php/c4913/) . This should give you some insight.

Orf
May 2nd, 2006, 02:21 PM
Hi Mike (your signature is great! :D )
The function in the article works the same way as my code: for each pixel calculates the luma level (in this case using different weights for R, G and B).
On an icon this is very fast, on 720*576 frames (@25 fps) this is a CPU eater... I'm looking for a shortcut here...
Ciao.

aewarnick
May 2nd, 2006, 04:34 PM
I highly doubt you'll find a GDI hardware accelerated method of doing this.

Orf
May 2nd, 2006, 04:46 PM
I agree, but I was looking for something more efficient than my code, not necessarily an hw accelerated solution.
Another opion in GDI+ and his ColorMatrix... maybe it uses SSE and MMX o improve speed? Anyone knows?

olivthill
May 2nd, 2006, 06:53 PM
The article, mentioned above, CreateGrayscaleIcon(), uses GetPixel() and SetPixel() which are slow APIs.
Here is another article about bitmap transformations. It show hows it is possible to work without using GetPixel() and SetPixel(): http://www.codeguru.com/cpp/g-m/gdi/article.php/c3693/

nolxev
May 3rd, 2006, 12:36 PM
Image editors uses ICS (image channel splitting). If the destination surface is an 8-bpp surface and its color table is set up to match the single-channel color scale, that channel of the original image will be converted to a grayscale image. You need to change only the color table later to be a grayscale color table. I did that with DIB section and ternary raster operations times ago.