I have a curius problem with my bitmap writing function, it takes a char array and writes a 24 bit BGR bitmap.

It was working fine using an array captured from a camera, I printed out the content of the first couple of bytes:

132 135 131
132 135 131
139 138 133
135 138 130
138 140 131
135 138 129
140 140 131

And my code below produces a lovely bitmap from that information, however, I am trying to average a load of these pictues and to do that I need to make my own array. I've made things really simple to demonstrate the problem I have.

The char array cb holds the info, written as 255,0,0 for each pixel. Using the same method above I printed out the array to file:

255 0 0
255 0 0
255 0 0
255 0 0
255 0 0
255 0 0
255 0 0

So its in exactly the same format as the working picture. However the image is not a solid blue bitmap, it consists of diagonal blue lines on a gray background in the pattern:

GBGGBGGBGGB
GGBGGBGGBGG
BGGBGGBGGBG

G= gray (204,204,204 if anyone is curious)
B= Blue 255,0,0

So its just either missing out every 2nd and 3rd pixel or placing the second pixel 3rd and the third pixel 6th etc. the code is below:

//declair a byte buffer to hold the information for the picture
	unsigned char  * cb = (unsigned char *)malloc(width*height*3);
	
	for (int j = 0 ; j < (width*height) ; j+=3)
	{
		cb[j*3] = 255;
		cb[j*3+1] = 0;
		cb[j*3+2] = 0;
	}

	HANDLE fh;
	DWORD nWritten;

	BITMAPFILEHEADER	hdr;
	BITMAPINFOHEADER	lpbi;
	
	// Fill in the fields of the file header 
	hdr.bfType		= ((WORD) ('M' << 8) | 'B');	// is always "BM"
	hdr.bfSize		= sizeof(hdr) + sizeof(BITMAPINFOHEADER) + pBufferSize;
	hdr.bfReserved1 	= 0;
	hdr.bfReserved2 	= 0;
	hdr.bfOffBits		= sizeof(hdr) + sizeof(BITMAPINFOHEADER);
	
	//Fill in the fields of the info header
	lpbi.biSize  = 40;
	lpbi.biWidth = width;
	lpbi.biHeight = height;
	lpbi.biPlanes = 1;
	lpbi.biBitCount = 24;
	lpbi.biSizeImage = pBufferSize;
	lpbi.biCompression = 0;
	lpbi.biXPelsPerMeter = 0;
	lpbi.biYPelsPerMeter = 0;
	lpbi.biClrUsed = 0;
	lpbi.biClrImportant = 0;
	
	fh = CreateFile(filename,
			GENERIC_WRITE, 0, NULL,
			CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	
	WriteFile(fh, &hdr, sizeof(hdr), &nWritten, NULL);
	WriteFile(fh,
			  &lpbi,
			  sizeof(lpbi), &nWritten, NULL);
	WriteFile(fh, cb, pBufferSize, &nWritten, NULL);

	CloseHandle(fh);

I just don't get how writing my own char* array could be different... its just data!

I would step back for a second and ask why you are writing your own bitmap writing function? I bet there are bunches of libraries that include such a thing. Then you can spend your time writing new code!

It seemed easier to write a (resonably) well documented couple of lines rather than spend time (and money?) on an external library.

This isn't actually going to be part of the final project, I will have to pass this to a java program which can't manage bitmaps anyway, I figured it would be easier keeping the c++ data as a byte array for messing arround with the image, so it seemed logical to just write a bitmap (however badly) so I can just see whats going on...

It makes sence to me!

The problem lies in the loop filling the bitmap data.

You can make a simple calculation of how many bytes you are writing - 3 each iteration, width*height/3 iterations - a total of width*height bytes, not pixels. Essentially, you're writing to every third pixel, hence the diagonal lines.

To correct the problem you should just replace the j+=3 in the loop with j++ .

commented: Thanks for taking the time to spot my mistake! +1

I can't belive I did that, I must have been doing it in two different ways in different places and then combined them...

Damn that copy and paste! I checked and I made the same mistake with the print outs aswell.

No I feel stupid >_< Thanks for spotting it!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.