Converting a color image to a grayscale image

Started by
10 comments, last by Scptre 21 years, 4 months ago
I am programming a small game for my computer science course and I was wondering if either Direct X or Windows GDI has a function that will let me convert a colored image to a grayscale image.
Advertisement
It can''t be hard doing it yourself.

I notice that Paint Shop Pro, when converting a color image to grayscale, converts red (255,0,0) to gray 76, green (0,255,0) to gray 150, and blue (0,0,255) to gray 28. 76+150+28 = 254, close to 255, which is white.

Therefore, probably to convert a picture to grayscale, you take the red component and multiply it by 76/255 (to scale it from 0..255 down to 0..76), multiply the green by 150/255, and the blue by 28/255 (be sure to use floating point and then convert to integer/byte). Then add those values together and that is the gray value.

So cyan (0,255,255) becomes 150+28 = gray 178, or RGB(178,178,178). Orange (255,128,0) becomes 76+75 = gray 151, or RGB(151,151,151).

~CGameProgrammer( );
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Ya that is what i was thinking of doing but it would be a very slow process when you have to do it for a 640x480 surface when you are doing it many times in a row.
The conversion for color to grayscale is:
R*0.30 + G*0.59 + B*0.11
since green is what our eyes are most sensitive to, then red, then blue, this will give a decent brightness level in the final grayscale image.

You can accomplish this in real-time on geforce-level hardware by using a dot3 operation. You can render your scene to a texture that can contain an image large enough to contain the backbuffer, then render that texture back into the backbuffer on a big quad using the dot3 operation. in d3d texture stage terms:

setrenderstate(texturefactor, ARGB(1, 0.30, 0.59, 0.11))
color arg1: tfactor
color arg2: texture containing final scene
color op: dotproduct3

hope this helps
Assassin, aka RedBeard. andyc.org
Wow!
It''s a very nice solution indeed
A real beauty !

I rushed to read the SDK on the dotproduct3 colorop
And I had to conclude: this will really work !

Except it doesn''t for me :-(

The dotproduct3 operand seems to do nothing at all
I just get the original texture

Can it be that this is not supported on my videocard ?
( it''s a Matrox G550 supposed to be of type Geforce2 )

Or may my choices of memorypool, usage and other parameters
be wrong when I create devices, textures and the like ?

I have also never got the MIPMAPLODBIAS to have any effect :-|
(if that could be in any way related ..)
well, i did this once. i sum all red, green, and blue components and divide it by 3, then use the result as your final red, green, and blue.

For example:
Red: 120
Green: 50
Blue: 100
Total = 120 + 50 + 100 = 270
Divide it by 3 = 270 / 3 = 90

New value:
Red: 90
Green: 90
Blue: 90

It works OK. I don''t know with Assasin''s method. Looks like it''s better.

My compiler generates one error message: "does not compile."
Fire up the DX Caps Viewer, and navigate down to
DirectX Graphics Adapters / video_card_here / D3D Device Types / HAL / Caps / TextureOpCaps

and see if it lists D3DTEXOPCAPS_DOTPRODUCT3 along with "Yes" in there. If not, then your card might not support the dot3 operation. If it says that the operation is supported, it could be something else. I'm not seeing a caps entry to indicate whether the texturefactor renderstate is supported, so I'm assuming that it's a required thing and should be there too.

The dot3 operation should replicate a single value throughout all the color channels (R,G,B, and alpha all get the same value) which should make it a grayscale image. I'm not sure if you're doing the whole render-to-texture thing, but you can probably get the same result by rendering your normal geometry using the same texture stage setup and putting in a default texture on the object instead of the texture holding the whole scene. That should basically just give you a grayscale representation of the texture applied to the object. You can get more fancy and throw lighting stuff into the mix too, but the basic effect should work if your hardware supports the dot3 operation.

[edited by - Assassin on November 21, 2002 4:13:18 AM]
Assassin, aka RedBeard. andyc.org
alnite: The reason you can''t average the red/green/blue is that they are not the same brightness. Green is brightest, then red, then blue.

~CGameProgrammer( );
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
quote:Original post by CGameProgrammer
alnite: The reason you can''t average the red/green/blue is that they are not the same brightness. Green is brightest, then red, then blue.


Well, I didn''t know about that technical stuff. I did it about three years ago in VB. But it still works. You get grayscale, not greenscale.

My compiler generates one error message: "does not compile."
Assassin thank you very much
You have been indbiocuousoelasicasicalistically helpful :-)

My D3DTEXOPCAPS_DOTPRODUCT3 is listed with "No" (under HAL)
:-(

The reference device says "yes" however
So I tried to create my device as a reference device

But that doesn''t work either ..

This topic is closed to new replies.

Advertisement