Reputation: 11
hi im trying to capture screenshot but the image comes out corrupted, can anyone see whats wrong wth the code, basically im trying to use createdibsection so i can accesss the bits directly.
heres what the resulting picture looks http://oi47.tinypic.com/33c4zko.jpg
bool FrameData::Create(int width, int height, ImageFormat imgFormat, HWND sourceWindow)
{
if(width < 0)
return false;
srcWndDC = GetDC(sourceWindow);
hdc = CreateCompatibleDC(srcWndDC);
if(hdc == nullptr || srcWndDC == nullptr)
{
return false;
}
memset(&bmpInfo, 0, sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = width;
bmpInfo.bmiHeader.biHeight = -height; // top-down
bmpInfo.bmiHeader.biPlanes = 1;
switch(imgFormat)
{
case ImageFormat::RGB16:
bmpInfo.bmiHeader.biBitCount = 16;
break;
case ImageFormat::RGB24:
bmpInfo.bmiHeader.biBitCount = 24;
break;
case ImageFormat::RGB32:
bmpInfo.bmiHeader.biBitCount = 32;
break;
default:
return false;
}
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = height * width * imgFormat;
hBitmap = CreateDIBSection(srcWndDC, &bmpInfo, DIB_RGB_COLORS, (void**)&bits, NULL, NULL);
if(hBitmap == nullptr)
{
return false;
}
return true;
}
bool FrameData::SaveFrameToFile(std::string& filename)
{
BITMAPFILEHEADER bmpFileHdr = {0};
bmpFileHdr.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
bmpFileHdr.bfType='MB';
bmpFileHdr.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
std::ofstream outfile;
outfile.open(filename);
if(!outfile.is_open())
{
return false;
}
outfile.write((char*)&bmpFileHdr, sizeof(BITMAPFILEHEADER));
outfile.write((char*)&bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER));
outfile.write((char*)bits, bmpInfo.bmiHeader.biSizeImage);
outfile.close();
return true;
}
thats the code, then i just use this to capture the screen
SelectObject(data.GetHDC(), data.GetHBitmap());
BitBlt(data.GetHDC(),0,0,data.GetWidth(), data.GetHeight(), data.GetSourceWindowDC(),0,0 , SRCCOPY | CAPTUREBLT);
Upvotes: 1
Views: 1341
Reputation: 162
Don't have time to check all the details of your bitmap structures initialization but try outfile.open(filename, ios_base::out + ios_base::bin);
instead of outfile.open(filename);
, else all your 0x0A bytes ('\n' or LineFeed) are replaced by 0x0D ('\r' or CarriageReturn) followed by 0x0A (2 bytes MS-DOS/Windows text file end-of-line sequence)!
Also I think that bmpInfo.bmiHeader.biSizeImage
should be something like height * 4 * (((width * bmpInfo.bmiHeader.biBitCount) + 0x1F) / 0x20)
(each row of pixels must be 32-bit aligned, resulting in up to 3 unused padding bytes at the end of each row, doesn't matter for RGB32 format).
Upvotes: 2