Corrupt Bitmaps? How is this possible?

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

Recommended Posts

I've wrote a Win32 console programs that takes screenshots of a game while its running. Here is the source.
/* Main procedure for the ScreenCapture component */
void sMovieMaker()
{
/* MovieMaker variables [Optimization Procedure] */
POINT xyMouse;
char strNumber[10];
unsigned short intFrame;

/* Determine the rectangle for the capture. */
printf("Enter the coordinates for the rectangle to be captured.\nX1:");
scanf("%d",&r.left);
printf("Y1:");
scanf("%d",&r.top);
printf("X2:");
scanf("%d",&r.right);
printf("Y2:");
scanf("%d",&r.bottom);

/* Create the surface for the capture. */
sCreateSurface(r.right - r.left, r.bottom - r.top, &hdcCapture);

/* Get the DC the Tibia Window [Optimization Procedure] */
dcTibia = GetDC(hwndTibia);

/* Precreate the BITMAP file structure [Optimization Procedure] */
ZeroMemory(&biBitmap,sizeof(biBitmap));
biBitmap.bmiHeader.biSizeImage=3*(r.right - r.left)*(r.bottom - r.top);
hdcBmpFileDC=CreateCompatibleDC(dcTibia);
hbBmpFileBitmap =CreateDIBSection(dcTibia,&biBitmap,DIB_RGB_COLORS,&pBits,NULL,0);
SelectObject(hdcBmpFileDC,hbBmpFileBitmap);

/* Ask the user for the frame-rate. */
printf("How many miliseconds between captures?\n");
scanf("%d", &intLoop);

/* Prompt the user that the capturing is about to begin. */
printf("Are you ready to begin recording (Y/N)?\n");
printf("(This program will halt for 3 seconds after your response to give you time to focus the Tibia window.)\n\n");
printf("To stop recording, move the mouse to point (0,0)!\n");
scanf("%s", strBuffer);

/* Handle the user's response. */
if (strBuffer[0] == 'Y' || strBuffer[0] == 'y' )
{
Sleep(3000);
printf("Recording started!");
intFrame = 0;
GetCursorPos(&xyMouse);
while(xyMouse.x != 0 || xyMouse.y != 0)
{
BitBlt(hdcBmpFileDC,0,0,r.right - r.left,r.bottom - r.top,dcTibia,r.left,r.top,SRCCOPY);
sBurnFile(intFrame);
sprintf(strNumber,"%d", intFrame);
printf("Recorded frame #%s.\n", strNumber);
intFrame++;
GetCursorPos(&xyMouse);
Sleep(intLoop);
}

}

/* Clean Up */
DeleteDC(hdcBmpFileDC);
DeleteObject(hbBmpFileBitmap);
printf("MovieMaker has ended.\n");
}
/* Helper: sMovieMaker -> Write file.*/
void sBurnFile(unsigned short intNumber)
{
char strFileName[30];
char strNumber[10];
HANDLE	hFile;
DWORD	dwRet;

/* Build the Filename. */
sprintf(strNumber, "%d", intNumber);
strcpy(strFileName, "Frame");
strcat(strFileName,strNumber);
strcat(strFileName,".bmp");

hFile=CreateFile(strFileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
dwRet=0;

CloseHandle(hFile);
}


When it runs, it produces the Bitmap, and its viewable in MSPAINT. But most other programs say the Bitmap is corrupt, such as WindowsXP Printer and Fax viewer, Zoner's GIF animator, Antechnius Animator, and several others. Whats wrong with it? Edit: Oops, almost forgot. Here are the global varibles in the program: since you might need em to find the problem.
/* MovieMaker */
HBITMAP hbBitmap;
void *pBits=NULL;
HBITMAP	hbBmpFileBitmap;
HDC dcTibia;
HDC hdcCapture;
RECT r;
BITMAPINFO	biBitmap;
HDC hdcBmpFileDC;


[Edited by - NetCoaster on October 14, 2004 12:29:11 PM]

Share on other sites
Hi man, I think your porblem is in the bitmap bit count.
I saw you use 24bits. (rarely supported by other programs)
Try using 32 bits.

Share on other sites
24-bit color bitmaps should be fine. What you need to be aware of is that each horizontal scanline is suppose to be DWORD aligned, i.e. some multiple of 4 bytes wide. For example, say you have a 10 by 10 bitmap, 24-bit color. You would think that each row of pixels should be 30 bytes wide (3 * 10). However, it actually needs to be 32 bytes wide, with the remaining two bytes a the end being padding; their values are ignored. Here's what I use to calculate the needed byte width per row:
ScanlineWidth = (3 * Width + 3) & (~0x3);

Thus the size of all of the bitmap data (biSizeImage) would be:
biSizeImage = ((3 * Width + 3) & (~0x3)) * Height;
Hope that [is indeed the problem and thus] helps.

Share on other sites
Quote:
 Original post by Agony24-bit color bitmaps should be fine. What you need to be aware of is that each horizontal scanline is suppose to be DWORD aligned, i.e. some multiple of 4 bytes wide. For example, say you have a 10 by 10 bitmap, 24-bit color. You would think that each row of pixels should be 30 bytes wide (3 * 10). However, it actually needs to be 32 bytes wide, with the remaining two bytes a the end being padding; their values are ignored. Here's what I use to calculate the needed byte width per row:ScanlineWidth = (3 * Width + 3) & (~0x3);Thus the size of all of the bitmap data (biSizeImage) would be:biSizeImage = ((3 * Width + 3) & (~0x3)) * Height;Hope that [is indeed the problem and thus] helps.

omg! I could kiss you.

That was the problem, and that would explain the buffer overflow errors I got when playing it in Media Player. And, I thought I would have to rewrite my whole capture code.. lol

THAKNK YOU AGONY!

Good answer ! :)

• 13
• 18
• 29
• 11
• 20