Advertisement

Bitmap color depth problem

Started by December 21, 1999 03:18 PM
15 comments, last by GameDev.net 24 years, 11 months ago
Or if your as lazy as me then you use the pre written code in the DDUtil.cpp (I think) that comes with the SDK.
I'm trying to write a bitmap.
Advertisement
I don't see what you are trying to do. Writing a bitmap or loading a bitmap.

Your last post looks like you are trying to write one. A BMP file I suppose....

Ok, one post of yours implies about 1, 4 and 8 bit. They are all paletized so what you are trying to do is right. But...when you want to either write 16, 24 or 32 bit to a bitmap file. You need to store all the values. Most of them stored as BGR or ABGR (you can leave the A unchecked, it's for transparency use).
To write you use an unsigned char, since each of them can contain a value from between 0 and 255.
Also remember to fill in all the parameters necessary in the BITMAPFILEHEADER and BITMAPINFOHEADER. If you write your own file format. Remember to take into account what you need to store and do with it.

I would suspect that you want to write something to make a screenshot. Since it is all stored on a DirectDraw Surface,......you lock the surface, and get a pointer to the lpSurface (pointer should be an unsigned char for both 32 and 24 bit surfaces). if it is a 16 bit surface..you'd better get a word. In THIS case you need to know what the video card uses, hence the ddsd.ddpfPixelFormat.dwRBitMask and the other values. try to get the real values out of it. (don't want to think too much now, but I believe it was like ((r << 3) >> 10, (g << 3) >> 5, b << 3) for a 1555. And ((r << 3) >> 11, (g << 2) >> 5, b << 3) for a 565...but I may well be wrong, it's out of my head.....note that this won't give you the real rgb values....but values like 31 or something.....I don't work with 16 bit anymore, so.......
You might want to take a look at
http://members.xoom.com/CJdeVos/index.htm

from there there is an article I wrote called 32, 24, 16 and 8 bit

I'm tired now, i probably forgot a lot but oh well.....


------------------
Dance with me......

Hmmmm, after I checked this site again and answered, I thought about implementing a screenshot option. So.....if you are interested, here's a part of the source code I just implemented. (NOTE, 24 bit surfaces only..easily changed to 32 bit though).

code:
#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)void WriteBitmap(){	unsigned char *Buffer;	int Pitch;	Buffer = LockSurface(backsurf, &Pitch);	char B = 'B';  // BM = 0x4d42	char M = 'M';		short Reserved1    = 0;    short Reserved2    = 0;    long  PixelOff     = 54;    long  Compression  = 0;    long  Cmpsize      = 0;    long  colors       = 0;    long  impcol       = 0;		DWORD widthDW = WIDTHBYTES(modewidth * 24);		long BitmapFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + widthDW * modeheight;	long Written = 0;		BITMAPINFOHEADER header;	header.biSize          = 40; 						// header size	header.biWidth         = modewidth;	header.biHeight        = modeheight;	header.biPlanes        = 1;	header.biBitCount      = modedepth;					// RGB encoded, 24 bit	header.biCompression   = BI_RGB;			// no compression	header.biSizeImage     = 0;	header.biXPelsPerMeter = 0;	header.biYPelsPerMeter = 0;	header.biClrUsed       = 0;	header.biClrImportant  = 0;		FILE *fp;		fp=fopen("temp.bmp","wb");	if (fp==NULL) 	{		//Can't open file for writing;		return;	}		// should probably check for write errors here...		fwrite((BYTE *)&(B), 1, 1, fp);                Written += 1;	fwrite((BYTE *)&(M), 1, 1, fp);                Written += 1;	fwrite((long *)&(BitmapFileSize), 4, 1,fp);	   Written += 4;	fwrite((int  *)&(Reserved1), 2, 1, fp);        Written += 2;	fwrite((int  *)&(Reserved2), 2, 1, fp);        Written += 2;	fwrite((long *)&(PixelOff), 4, 1, fp);         Written += 4;		fwrite((BITMAPINFOHEADER *)&header, sizeof(BITMAPINFOHEADER),1,fp);	Written += sizeof(BITMAPINFOHEADER);		long row = 0;	long RowIndex;	long row_size;	row_size = header.biWidth * 3;    long ReadCount;	for (row = header.biHeight-1; row >= 0; row--) 	{		RowIndex = (long unsigned)row * row_size;						      				// write a row		ReadCount = fwrite((void *)(Buffer + RowIndex), row_size, 1, fp);		if (ReadCount != 1) 		{			//fwrite error....Giving up;			break;		}		Written += row_size;					// pad to DWORD...so that the image won't look 'weird' ie. like /		for (DWORD count = row_size; count < widthDW; count++) 		{			char Nothing = 0;			fwrite(&Nothing, 1, 1, fp);			Written++;							  		}	}	fclose(fp);	UnlockSurface(backsurf);}

There is, however, a small problem I encountered after writing this down, and checking. And that is that.......some parts of the lines I displayed on the screen didn't appear on the bitmap.

I'll look for the solution though.

Also an article about writing bitmaps will appear on my site soon, as I found quite a lot of questions about it.

------------------
Dance with me......

No wonder....i forgot the pitch

change that one line into

RowIndex = (long unsigned)row * Pitch;

------------------
Dance with me......

http://members.xoom.com/CJdeVos/index.htm

I do the following to load a bitmap and set a ddraw surface to it's bit depth.

hbmp = (HBITMAP)LoadImage(hInst, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(hbmp, sizeof(BITMAP), &bm);
ddsd.ddpfPixelFormat.dwRGBBitCount = bm.bmBitsPixel;

The bitmap I am loading is 8 bit, but the surface is always set to the depth of the screen resolution. i checked, and bm.bmBitsPixel is this value too. What do i need to do to get the proper bit depth of the bitmap?

Advertisement
Thank you all for your help. To tell you the truth, I had to figure it all out on my own. But I do appreciate all the effort oyu guys put into trying to help me.

This topic is closed to new replies.

Advertisement