Sign in to follow this  

[C++] Strange Problem with CreateDIBSection

This topic is 3554 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there, I have a RGB-Array which stores RGB values one after each other (R G B R G B ...). From this array I want to get a HBITMAP. I thought I use CreateDIBSection to get a memory pointer in which I can write directly on the one hand and have an hBitmap on the other hand. After I recognized that the memory I get allocated works with BGR instead of RGB (and I have no clue why one would do this..?) I faced another problem: Somehow does my calculation of the with [in bytes] of one line does not fit with what the system expects... For example I want want to draw alternating white and grey lines (starting from the bottom) - with my code I get the following result: result The code I work with it:
BITMAPINFOHEADER	bmih;
	HBITMAP hBitmap;
	BYTE * pBits;

	ZeroMemory(&bmih, sizeof(BITMAPINFOHEADER));

	bmih.biSize			= sizeof (BITMAPINFOHEADER);
	bmih.biWidth		= width;
	bmih.biHeight		= height; // bottom up
	bmih.biPlanes		= 1;
	bmih.biBitCount		= 24;
	bmih.biCompression	= BI_RGB;
	bmih.biSizeImage	= bmih.biWidth * bmih.biHeight * bmih.biBitCount / 8;

	hBitmap = CreateDIBSection(NULL, (BITMAPINFO *) &bmih, DIB_RGB_COLORS,
		(void**)&pBits, NULL, 0);
	
	for (int line = 0; line < height; line++) {
		if ((line % 2) == 0) {
			// white line
			memset(&(pBits[line * width * 3]),255,width * 3);
		} else {
			// grey line
			memset(&(pBits[line * width * 3]),200,width * 3);
		}
	}



It seems that I can partly fix the result by changing the loop:
int temp = 0;

	for (int line = 0; line < height; line++) {
		if ((line % 2) == 0) {
			// white line
			memset(&(pBits[line * width * 3 + temp]),255,width * 3);
		} else {
			// grey line
			memset(&(pBits[line * width * 3 + temp]),200,width * 3);
		}
		temp += 2;
	}


partly, because the result looks now like: result And despiet this - why should I two extra Bytes each line? I have absolutely no clue what is wrong with this - can you please give me a hint? thanks in advance, Tom

Share this post


Link to post
Share on other sites
There are a couple issues to be aware of:

  1. BITMAPINFO and BITMAPINFOHEADER are not the same thing! Why are you casting a BITMAPINFOHEADER as BITMAPINFO?

  2. DIB widths are always a multiple of 4. If your image is not naturally a multiple of 4 pixels wide, then the row is padded out with 0 until it is. Your sample image is 170 pixels, which isn't a multiple of 4. The next multiple of 4 is 172, hence the two extra bytes.

Share this post


Link to post
Share on other sites
Thank you very much :)

to 1.; Yes, this is true - but since BITMAPHEADERINFO is the first part of BITMAPINFO (in memory) and I thought CreateDIBSection() reads only the BITMAPHEADERINFO part it would work out - I tryed with BITMAPINFO also, and the same problem occured.

Your second suggestion makes absolutely sense, this explains everything - Is there a way to work around this, so that I could youse DIBs with no multiple of 4 width?

again, thank you very much

Share this post


Link to post
Share on other sites
Casting the BITMAPINFO into a BITMAPINFOHEADER probably works for what you have, but depending on which of BITMAPINFO's members you set, CreateDibSection may try to look into BITMAPINFOHEADER for certain information, and cause an error. Unless Microsoft has documented that what you're doing is sanctioned as far as their concerned, then I would definitely avoid it since its little more trouble to do it the right way.

As for the padding, there is unfortunately no way to over-ride the padding that I'm aware of. Its just how Microsoft has decided DIBs should work, because it allows them to make optimizations on the back-end. you'll just have to deal with it [grin]

Share this post


Link to post
Share on other sites
sure, one can't make it wrong by changing the BITMAPINFOHEADER to a BITMAPINFO - I'll do this.

Thanks for your suggestions - it solved my problems. I go line by line through the data, swap the R and the B Byte (because of the BGR organisation) and add padding if there is need to. Thanks

Share this post


Link to post
Share on other sites

This topic is 3554 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this