Bol Baba
Bol Baba

Reputation: 11

Bitblt,createdibsection, image comes out corrupted

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

Answers (1)

Christophe Bouchon
Christophe Bouchon

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

Related Questions