Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Hi! I am trying to create a bmp fi

Status
Not open for further replies.

VCproblems

Programmer
Apr 25, 2002
10
IN
Hi!
I am trying to create a bmp file with the following code:


CDibClass::CDibClass()
{
memset(&m_bmpInfoHdr, 0, sizeof(BITMAPINFOHEADER));
m_pBits = NULL;
m_pBMI = NULL;
}
CDibClass::~CDibClass()
{
CloseAll();
}
void CDibClass::CloseAll()
{
if (m_pBMI)
free(m_pBMI);
if (m_pBits)
free(m_pBits);
m_pBits = NULL;
m_pBMI = NULL;
}
void CDibClass::DibInit(int w, int h,LPCTSTR filename)
{
CloseAll();
BITMAPFILEHEADER bfh;
char *ch;
ch =(char*) &bfh.bfType;
*ch='B';
ch++;
*ch='M';
bfh.bfReserved1 =0;
bfh.bfReserved2 = 0;
bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD) + (w*h); bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
fp = fopen(filename,"wb+");
fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fp);
int i;
m_Width = w;
m_Height = h;
m_bmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);
m_bmpInfoHdr.biWidth = w;
m_bmpInfoHdr.biHeight = h;
m_bmpInfoHdr.biPlanes = 1;
m_bmpInfoHdr.biBitCount = 8; //24; m_bmpInfoHdr.biCompression =BI_RGB;
m_bmpInfoHdr.biSizeImage = 0 ; //w * h;m_bmpInfoHdr.biClrUsed32; //256;
m_bmpInfoHdr.biClrImportant = ; //256;
m_bmpInfoHdr.biXPelsPerMeter = 0;m_bmpInfoHdr.biYPelsPerMeter = 0;
m_pBMI = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD));
memcpy(m_pBMI, &m_bmpInfoHdr, sizeof(BITMAPINFOHEADER)); fwrite(&m_bmpInfoHdr,sizeof(BITMAPINFOHEADER),1,fp);
BYTE temp = 0;
BYTE temp1 = 255;
for(i=0; i < 256; i++)
{
m_pBMI->bmiColors.rgbRed = i;
m_pBMI->bmiColors.rgbGreen = i;
m_pBMI->bmiColors.rgbBlue = i;
m_pBMI->bmiColors.rgbReserved = 0;
fwrite(&i,sizeof(BYTE),1,fp);
fwrite(&i,sizeof(BYTE),1,fp);
fwrite(&i,sizeof(BYTE),1,fp);
fwrite(&temp,sizeof(BYTE),1,fp);
}
}
void CDibClass::SetBits(HDC hdc,const BYTE* pBits, const int size)
{
if (m_pBits)
free(m_pBits);
m_pBits = (BYTE*)malloc(size);
LPBYTE temp = new BYTE[size];
LPBYTE temp2 = new BYTE[size];
int i;
for(i = 0; i < size; i++)
{
temp = pBits[size - i];
}
for(int line = 0; line < m_Height; line++)
{
for(int row = 0; row < m_Width; row++)
{
temp2[line * m_Width + row] = temp[line * m_Width - row + m_Width];
}
}
for (int j = 0; j < m_Height; j++)
{
memcpy(&m_pBits[j*m_Width], &temp2[(m_Height - 1 - j) * m_Width], m_Width);
fwrite(&m_pBits[j*m_Width],m_Width,1,fp);
}
fclose(fp);
int scanline = SetDIBitsToDevice (hdc, 0, 0, m_Width, m_Height,0, 0, 0, m_Height,temp2, (LPBITMAPINFO) m_pBMI, DIB_RGB_COLORS);

delete [] temp;
delete [] temp2;
}


The code used to call the above functions is as follows:-



g_DibCtl->DibInit(devList.imgSize.width,devList.imgSize.height, filename);
g_DibCtl->SetBits(hdc,g_FPBuffer,devList.imgSize.width*devList.imgSize.height );



The problem that i am facing is : the bitmap is blank, if the bmp file is selected(e.g. in explorer), the preview is not available.If i try to open the bmp file in microsoft photo editor, an error : &quot;Error Reading File&quot; occurs. And if opened in Paint the bmp file is blank.

what is wrong?
Please help me and tell me the possible problem.
Thanks.

 
here is a block of code I used a while back... I dont know if it is what you are looking for. Also, The stuff dealing with palette size is not required (I dont think). I haven't had time to go through the bitmap processing your doing but this may help. When I have time today, I will try to pinpoint where things are going wrong.

Matt


Code:
========================================================================================================================
BITMAPINFO* pBMI = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + 256*sizeof(RGBQUAD));
		DWORD dwDibSize = 0;

		for(int i = 0;i<256;i++)
		{
			pBMI->bmiColors[i].rgbRed =
			pBMI->bmiColors[i].rgbGreen=
			pBMI->bmiColors[i].rgbBlue=i;
			
			pBMI->bmiColors[i].rgbReserved=0;
		}

		pBMI->bmiHeader.biWidth = pStill->GetWidth();
		pBMI->bmiHeader.biHeight = pStill->GetHeight();
		pBMI->bmiHeader.biClrUsed = 0;
		pBMI->bmiHeader.biPlanes = 1;
		pBMI->bmiHeader.biCompression = BI_RGB;
		pBMI->bmiHeader.biBitCount = 8;	
		pBMI->bmiHeader.biSizeImage = pStill->GetHeight()*pStill->GetWidth();
		pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
		pBMI->bmiHeader.biClrImportant=0;
		pBMI->bmiHeader.biXPelsPerMeter=0;
		pBMI->bmiHeader.biYPelsPerMeter=0;

		dwDibSize = *(LPDWORD)(&pBMI->bmiHeader) + ::PaletteSize((LPSTR)(&pBMI->bmiHeader));

		BITMAPFILEHEADER bfh;
		bfh.bfType=0x4d42;
		bfh.bfSize=pStill->GetHeight()*pStill->GetWidth() + sizeof(BITMAPFILEHEADER);
		bfh.bfReserved1 = 0;
		bfh.bfReserved2 = 0;
		bfh.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

		CFile tmp;
		tmp.Open(&quot;C:\\temp.bmp&quot;,CFile::modeWrite|CFile::shareDenyNone|CFile::modeCreate);
		tmp.Write(&bfh,sizeof(BITMAPFILEHEADER));
		tmp.Write((&pBMI->bmiHeader), *(LPDWORD)(&pBMI->bmiHeader) + ::PaletteSize((LPSTR)(&pBMI->bmiHeader)));
		tmp.Write(bmpBytes,pStill->GetHeight()*pStill->GetWidth());
 
Hi Matt!

Thanks a lot for your help. Actually the program you have sent is right but then the problem is not solved with the code u sent. The result is the same. Any other possible reason for the problem? The bitmap i am trying to write to a file is also a grayscale bitmap.
 
Well, lets try this. Lets just make a black bitmap. Lets say the height and width are 100 so our bmpBits will be a byte buffer defined as

BYTE bmpBits[100*100*<samples per pixel>]

in this case samples per pixel is 1 so it is just 100*100


I just tested this and it created one fine... just cut and paste into a MFC based conslole app... Just a side note, i didnt put in the frees so it leaks

Matt

Code:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;
	
	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T(&quot;Fatal Error: MFC initialization failed&quot;) << endl;
		nRetCode = 1;
	}
	else
	{

		// This is for grayscale only
		BITMAPINFO* pBMI = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + 256*sizeof(RGBQUAD));
        DWORD dwDibSize = 0;
		
		// Grayscale palette
        for(int i = 0;i<256;i++)
        {
            pBMI->bmiColors[i].rgbRed =
				pBMI->bmiColors[i].rgbGreen=
				pBMI->bmiColors[i].rgbBlue=i;
            
            pBMI->bmiColors[i].rgbReserved=0;
        }
		
        pBMI->bmiHeader.biWidth = 100;
        pBMI->bmiHeader.biHeight = 100;
        pBMI->bmiHeader.biClrUsed = 0;
        pBMI->bmiHeader.biPlanes = 1;
        pBMI->bmiHeader.biCompression = BI_RGB;
        pBMI->bmiHeader.biBitCount = 8;    
        pBMI->bmiHeader.biSizeImage =10000;
        pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
        pBMI->bmiHeader.biClrImportant=0;
        pBMI->bmiHeader.biXPelsPerMeter=0;
        pBMI->bmiHeader.biYPelsPerMeter=0;
		
		
        BITMAPFILEHEADER bfh;
        bfh.bfType=0x4d42;
        bfh.bfSize=10000 + sizeof(BITMAPFILEHEADER);
        bfh.bfReserved1 = 0;
        bfh.bfReserved2 = 0;
        bfh.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
		
		BYTE bmpBytes[10000];
		memset(bmpBytes,0,10000);

        CFile tmp;
        tmp.Open(&quot;C:\\temp.bmp&quot;,CFile::modeWrite|CFile::shareDenyNone|CFile::modeCreate);
        tmp.Write(&bfh,sizeof(BITMAPFILEHEADER));
        tmp.Write((&pBMI->bmiHeader), *(LPDWORD)(&pBMI->bmiHeader) +  256*sizeof(RGBQUAD));
        tmp.Write(bmpBytes,10000);
		
	}
	
	return nRetCode;
}


 
Hi Matt!
The code you sent works fine i.e. generates a black bitmap without any problem.Can you send me an example of a byte buffer which generates an image? Because i think there is some problem with the byte buffer i am using.
Thanks a lot for your prompt replies and help.
 
Hi Matt!
The code you sent works fine i.e. generates a black bitmap without any problem.Can you send me an example of a byte buffer which generates an image? Because i think there is some problem with the byte buffer i am using.
Thanks a lot for your prompt replies and help.
 
A byte buffer that is actually something I dont think i could post... What you could try is making a 256 by 256 bitmap and doing stripes across it. They will be grayscale stripes but it shouldnt be that tough to do.


Code:
BYTE buffer[256*256];
BYTE* ptr = buffer;
for(int i = 0;i<256;i++)
{
   memcpy(ptr,i,256);
   ptr+=256;
}

What this should produce is an image that goes from black to white from top to bottom.

Matt
 
Hi Matt!
The code you sent for creating a bitmap file really helped a lot. Now i am able to write the bitmap into a file without any problem. But now i guess there is a problem with the buffer that i am using to write into the file coz the image that i get out of the buffer is not straight, instead its slanted.
Thanks a lot for your help.
 
Does it look like the verticle hold went out on a tv screen?

Matt
 
Hi Matt!
Yes it kind of looks that way. The image is tilted diagonally. The image that i want forms a diagonal going from left top corner to the right bottom of the rectangular area that holds it.
 
YOu are aligning the bitmap improperly. Try to put it on a quad boundary I.E. Height and width are divisable by 4. The only tough part is taht you will have some extra width or height on your image.

The other option is to remove rows or columns until you get the quad boundry

Matt
 
Hi Matt!
Any other ideas for the alignment. I have tried a lot over this i.e. to get the alignment and also adjusting the height and the width in such a way that they are divisible by 4 but it hardly worked. And another thing is i also get more than one images i.e. 3 images in the same rectangular area, all of them are not complete, only the middle one is complete.
 
Ok, what exactly are you trying to do? Maybe that will give me some insight into how I can help :)

Matt
 
Hi Matt!
Well heres what i tried :
for(int k = 0;k < height*width; k++)
{
int y = k/width;
int x = k%width;
int n = ((y-1)*width)+x;
Bytes[n] = pbmpBytes[n-y];
}
In this case pbmpBytes is the buffer holding the bytes for the image. The size of this buffer is height*width. &quot;Bytes&quot; is another buffer of the same size into which i am copying the changed value.This pbmpBytes is what i am trying to preprocess before writing into the file. The processing done on the byte buffer is to move each pixel widthwise. In this case the width i have is 358 and the height is 284. I also tried to change the width and height but in vain.
 
The first time through the loop your setting

Bytes[NEGATIVE ONE] = pbmpBytes[NEGATIVE ONE MINUS ZERO]

This should be causing a problem.

Also, until k >= width you will continue to have this problem. Your algorithm is off.

Matt
 
Hi Matt!
I have finally got the image straight, with a little more processing on the buffer.
Thanks a lot for your help.
 
Hi everybody,

i would like translate a bitmap 24 bit into 8 bits. how can i do, please. I can read the bitmap File and info header of my 24 bitmap but I want to write one int 8 bitmap (in gray scale).

Thanks to help me,

Tonio
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top