Bitblt, createdibsection, изображението излиза повредено

здравейте, опитвам се да направя екранна снимка, но изображението излиза повредено, може ли някой да види какво не е наред с кода, основно се опитвам да използвам createdibsection, за да мога да получа директен достъп до битовете.

ето как изглежда получената снимка 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;
}

това е кодът, тогава просто използвам това, за да заснема екрана

 SelectObject(data.GetHDC(), data.GetHBitmap());
 BitBlt(data.GetHDC(),0,0,data.GetWidth(), data.GetHeight(),           data.GetSourceWindowDC(),0,0 , SRCCOPY | CAPTUREBLT);

person Bol Baba    schedule 14.07.2012    source източник


Отговори (1)


Нямате време да проверявате всички подробности за инициализацията на вашите растерни структури, но опитайте outfile.open(filename, ios_base::out + ios_base::bin); вместо outfile.open(filename);, в противен случай всичките ви 0x0A байтове ('\n' или LineFeed) се заменят с 0x0D ('\r' или CarriageReturn), последвано от 0x0A (2 байта MS-DOS/Windows текстов файл в края на реда)!

Също така мисля, че bmpInfo.bmiHeader.biSizeImage трябва да бъде нещо като height * 4 * (((width * bmpInfo.bmiHeader.biBitCount) + 0x1F) / 0x20) (всеки ред от пиксели трябва да бъде 32-битов подравнен, което води до 3 неизползвани байта за допълване в края на всеки ред, няма значение за RGB32 формат).

person Christophe Bouchon    schedule 14.07.2012
comment
+1. Ако това се случва, размерът на файла трябва да е различен от това, което се очаква от броя на пикселите, така че това е лесно за проверка. - person ; 14.07.2012
comment
Не забравяйте да преброите и байтовете на заглавките. - person Christophe Bouchon; 14.07.2012