Advertisement

Bitmap formats and colors

Started by September 20, 2000 10:41 AM
12 comments, last by Scooter 24 years, 3 months ago
Hey, I need help getting the RED value from a 16bit bitmap. Here''s the specifics: I''m using DirectX7 so i''ll load the bitmap via LoadImage() and blit it onto a surface then i have the handle to the surface from which i can extract the colors, the prob is here, i don''t know how to extract just the red from the 16bit bitmap. (note,in case you had a brain fart, getting it for 16bit bitmap is different from getting it from a 32bit bitmap) Thanks in advance for any comments/suggestions.
We are here just like this,It really doesn't matter why.The world is here like it is,'We could laugh we could cry.Is it good or is it bad,Wright or maybe wrong?There's no use of being sad,Without a purpose within a song.
There was recently another thread about this subject. I can't make the damn link show up here for some reason, but this is the URL: http://www.gamedev.net/community/forums/topic.asp?topic_id=25423&forum_id=10&Topic_Title=I+need+some+help+with+DirectDraw+%3A%29&forum_title=&M=True&S=True

I have some code for that, and I will post it here this evening.

Rath

____________________________________________________

"Two wrongs do not make a right; it usually takes 3 or more."



Edited by - Ratheous on September 20, 2000 12:38:11 PM

____________________________________________________
"Two wrongs do not make a right; it usually takes 3 or more."
Some mistakes are too much fun to only make once.
Never anger a dragon, for you are crunchy and you go well with brie.

Advertisement
You want to extract the red color from a surface, right?
Here you go:

            typedef unsigned short USHORT;LPDIRECTDRAWSURFACE7 lpdds; // surfaceDDSURFACEDESC2 ddsd;memset(&ddsd,0,sizeof(ddsd));ddsd.dwSize = sizeof(ddsd);lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL); // Lock the surface hereint lpitch = ddsd.lPitch >> 1; // get the right pitchUSHORT *lpsurface = (USHORT*)ddsd.lpSurface; // the surfaceint x = 5, y = 6; // the place you want to get the colorUSHORT color = lpsurface[x + y*lpitch];int red = (color & 0xF800) >> 11;int green = (color & 0x07E0) >> 6;int blue = color & 0x001F;lpdds->Unlock(NULL);            


That's pretty much it
You got the red, green and blue values.
This will only work for 565 btw, I think shifting the green value only 5 times will make it work with 555.


- Goblineye Entertainment
The road to success is always under construction

Edited by - Tornado on September 21, 2000 8:14:43 AM
Goblineye EntertainmentThe road to success is always under construction
That might work on some cards but if you want it to work everywhere you need to get the pixel format and bit masks for the diferent types of 16bit modes.
These are:
555 RGB
565 RGB
565 BGR (rarely supported)



____________________________________________________

"Two wrongs do not make a right; it usually takes 3 or more."

____________________________________________________
"Two wrongs do not make a right; it usually takes 3 or more."
Some mistakes are too much fun to only make once.
Never anger a dragon, for you are crunchy and you go well with brie.

I''m basically just learning the basics of DirectDraw at the moment and I''m using LaMothes GPDUMB engine to play around with various things... everytime I try to load a 16bit image it always ends up being corrupted, with just green and blue as the only colors. The same happens when I try any kind of random line/pixel drawing program, everything works fine in 8bit, so its a problem I guess with my Vid card (G400 MAX), theres no mention in it of these 565, 555 modes, this could well be the problem... anyone got any ideas how I could fix this?

-Charles "MrBlonde" Palmer
=========================
mrblonde@stomped.com
S T O M P E D
-Charles "MrBlonde" Palmer ========================= mrblonde@stomped.com S T O M P E D
quote: Original post by Ratheous

the diferent types of 16bit modes.
These are:
555 RGB
565 RGB
565 BGR (rarely supported)



Firstly, 555 doesn''t add up to 16, and 565 is the only 16 bit pixel format used on a dd surface - BGR is for windows GDI surfaces

Tornados code will do it.
Advertisement
565 RGB is NOT the only pixel format supported by DDraw.

555 doesn''t add up to 16, but who says that all 16 bits must be used? The highest bit is just ignored. 555 is a valid format, and DDraw should be able to create and use surfaces with that pixel format (although there''s no guarantee that it will be supported by the driver, so be careful).
565 BGR should also be supported by DDraw, although I can''t see any reason that you''d want to use it. It offers no advantage over RGB, it may not be suported in hardware, and even if it is, there''s a good chance that the driver support is minimal.
Finally (and most importantly), don''t forget about 1555 ARGB format.

In general, it''s safest to stick to 565 format, and explicitly ask for that format when you create your surfaces. However, if you don''t specify the pixel format you can NOT assume 565. You should either check for it and error out if it''s anything else, or you should write code to detect the masks and shift values from the PIXELFORMAT in the surface description.

...Syzygy
Thanks All.
We are here just like this,It really doesn't matter why.The world is here like it is,'We could laugh we could cry.Is it good or is it bad,Wright or maybe wrong?There's no use of being sad,Without a purpose within a song.
Tornado, I''ve noticed a problem, what i did was extract the red value for every pixel and store it in an array now when i look at the array it is not in the correct order. Meaning the width starts in like the middle and goes to the edge then wraps around the other side. seems like an offset is wrong somewhere. Or did i do the array wrong (focusing just on red)? ?

USHORT color[NUMVERTS];
DWORD red[NUMVERTS];

for (int n=0; n < NUMVERTS; n++)
{
color[n] = lpsurface[x + y*lpitch];
if (x >=127) //width - 1 (stars a zero)
{
x = 0;
y += 1;
}
x++;
}

for (int z=0;z < NUMVERTS;z++)
{
red[z] = (color[z] & 0xF800) >> 11;
}

NUMVERTS is 16384 of course 128*128 = size of bitmap
We are here just like this,It really doesn't matter why.The world is here like it is,'We could laugh we could cry.Is it good or is it bad,Wright or maybe wrong?There's no use of being sad,Without a purpose within a song.
I'm not sure I understand what your doing exactly in your code, but here's how I would do it:

            typedef unsigned short USHORT;#define width 128#define height 128DWORD Red_Array[width][height];LPDIRECTDRAWSURFACE7 lpdds; // surfaceDDSURFACEDESC2 ddsd;memset(&ddsd,0,sizeof(ddsd));ddsd.dwSize = sizeof(ddsd);lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL); // Lock the surface hereint lpitch = ddsd.lPitch >> 1; // get the right pitchUSHORT *lpsurface = (USHORT*)ddsd.lpSurface; // the surfacefor (int x=0;x < width;x++) for (int y=0;y < height;y++)  Red_Array[x][y] = ((lpsurface[x + y*lpitch]) & 0xF800) >> 11;            


Note that I made the red array a double array. Easier to use
Also, DWORD might be a little more than needed for the red color, USHORT might be better. But It'll work either way

Edited by - Tornado on September 21, 2000 9:33:37 AM
Goblineye EntertainmentThe road to success is always under construction

This topic is closed to new replies.

Advertisement