hi all,

i'm having some problems with the GetDIBits function.
i wrote this code that saves the pixels from a rectangle from my window as a bmp file, and this all works well under win98 and win98se but under xp professional when i open the bmp file it is full with black pixel a contrary under win9x i've got the picture that i wanted to save. so there must be something that i didn't quiet set up that is needed under xp i just don't know what. here is the code:


case IDM_SAVE: // Menu: File -> Save as BMP
                  {
                  HDC hdc;
                  DWORD dwBytesWritten,
                        dwBmpWidth=dParams.sigRect.right-dParams.sigRect.left-3-1,
                        dwBmpHeight=dParams.sigRect.bottom-dParams.sigRect.top-3; // 3 pixels for the borders

                  // the next 2 structures are composing together the header of a bmp file

                  BITMAPFILEHEADER bf={(short)('B'|('M'<<8)),0,0,0,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)};
                  BITMAPINFOHEADER bh={sizeof(BITMAPINFOHEADER),dwBmpWidth,dwBmpHeight,1,24,0,0,0,0,0,0};
                  BITMAPINFO bn;
                  RECT rc;
                  HBITMAP hbmp;
                  BYTE* buffer;
                  HANDLE hFileBmp;

                  // create a file and write the bmp header into it

                  wsprintf(str,"capture%d.bmp",dwBmpsCaptured++);
                  hFileBmp=CreateFile(str,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
                  WriteFile(hFileBmp,&bf,sizeof(BITMAPFILEHEADER),&dwBytesWritten,NULL);
                  WriteFile(hFileBmp,&bh,sizeof(BITMAPINFOHEADER),&dwBytesWritten,NULL);

                  // prepare the bitmap for further operations

                  GetClientRect(hwnd,&rc);
                  hdc=GetDC(hwnd);
                  hbmp=CreateCompatibleBitmap(hdc,rc.right,rc.bottom);
                  buffer=(BYTE*)LocalAlloc(LMEM_FIXED,3*rc.right);

                  // setup properties for the bitmap from we want to retrieve the scanlines

                  ZeroMemory(&bn,sizeof(BITMAPINFO));

                  bn.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
                  bn.bmiHeader.biWidth=rc.right;
                  bn.bmiHeader.biHeight=rc.bottom;
                  bn.bmiHeader.biPlanes=1;
                  bn.bmiHeader.biBitCount=24;
                  bn.bmiHeader.biCompression=BI_RGB;

                  // read the scanlines one by one into the buffer and write out the appropriate part of the buffer into the file

                  for (i=rc.bottom-dParams.sigRect.bottom+2; i<dwBmpHeight+rc.bottom-dParams.sigRect.bottom+2; i++)
                    {

                    // read the pixels into the buffer where 3 bytes in the buffer represents 1 pixel (aka the picture is a 24bit bmp file)

                    GetDIBits(hdc,hbmp,i,1,buffer,&bn,DIB_RGB_COLORS);

                    // write the part of the scanline (which actually represents the picture) to the file

                    WriteFile(hFileBmp,&buffer[(dParams.sigRect.left+2)*3],dwBmpWidth*3,&dwBytesWritten,NULL);
                    }

                  // better clean up this mess i've just made :)

                  CloseHandle(hFileBmp);
                  LocalFree(buffer);
                  DeleteObject(hbmp);
                  ReleaseDC(hwnd,hdc);
                  } break;


i know this is c, but i assume if someone knows win32asm then (s)he also must know c too.

so i don't know what i could do wrong, first i thought that because of the source bitmap (that i create with CreateCompatibleBitmap) is 32bits (i checked this with GetObject) so i must convert it somehow to 24 bits, but then i learned that GetDIBits is doing that conversion for me. oh and just in case dParams.sigRect is the RECT that contains the co-ordinates of the rectangle that i want to save as a BMP file.

so the thing is when i debug the code & i execute the GetDIBits(hdc,hbmp,... line it returns 1 in eax, which means that the function is successfull by the win32 documentation, the only catch is that it doesn't fills my buffer with the color bits but rather fills it with zeros. and this is the problem. oh and this particular line under 9x works as i would expect, i checked that too.

if anyone knows why is this please, reply, i would really appreciate it, thanx 4 listening,,,
Posted on 2005-08-11 03:19:32 by berril
yeah, had my troubles with that api, too.

the only catch is that it doesn't fills my buffer with the color bits but rather fills it with zeros. and this is the problem.


the nice part about 24-bit bitmaps is that they do not require a color table as the raw bitmap data is directly interpreted as rgbs (3 bytes -> 24 bit).
:mad: unfortunately i'm at work for some more hours, but i got a file called "bmp.inc" back at home that
might be interesting for you. lets see later on...
Dominik
Posted on 2005-08-11 06:01:20 by Dom