Как получить байтовое представление BITMAPFILEHEADER и BITMAPINFOHEADER? - PullRequest
0 голосов
/ 16 января 2020

Я пытаюсь сделать снимок экрана моего компьютера с помощью кода, а затем сохранить байты этого изображения в массив, а не сразу сохранить изображение, используя следующую функцию:

void WINAPI CaptureScreenIntoByteArray(
   BYTE*& screen_bytes,
   DWORD& screen_bytes_size)
{
   BITMAPFILEHEADER bfHeader;
   BITMAPINFOHEADER biHeader;
   BITMAPINFO bInfo;
   HGDIOBJ hTempBitmap;
   HBITMAP hBitmap;
   BITMAP bAllDesktops;
   HDC hDC, hMemDC;
   LONG lWidth, lHeight;
   BYTE* sb = NULL;

   ZeroMemory(&bfHeader, sizeof(BITMAPFILEHEADER));
   ZeroMemory(&biHeader, sizeof(BITMAPFILEHEADER));
   ZeroMemory(&bInfo, sizeof(BITMAPINFO));
   ZeroMemory(&bAllDesktops, sizeof(BITMAP));

   hDC = GetDC(NULL);
   hTempBitmap = GetCurrentObject(hDC, OBJ_BITMAP);
   GetObjectW(hTempBitmap, sizeof(BITMAP), &bAllDesktops);

   lWidth = bAllDesktops.bmWidth;
   lHeight = bAllDesktops.bmHeight;

   DeleteObject(hTempBitmap);

   bfHeader.bfType = (WORD)('B' | ('M' << 8));
   bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

   biHeader.biSize = sizeof(BITMAPINFOHEADER);
   biHeader.biBitCount = 24;
   biHeader.biCompression = BI_RGB;
   biHeader.biPlanes = 1;
   biHeader.biWidth = lWidth;
   biHeader.biHeight = lHeight;

   bInfo.bmiHeader = biHeader;

   screen_bytes_size = (((24 * lWidth + 31) & ~31) / 8) * lHeight;

   hMemDC = CreateCompatibleDC(hDC);
   hBitmap = CreateDIBSection(hDC, &bInfo, DIB_RGB_COLORS, (VOID**)&sb, NULL, 0);
   SelectObject(hMemDC, hBitmap);

   int x = GetSystemMetrics(SM_XVIRTUALSCREEN);
   int y = GetSystemMetrics(SM_YVIRTUALSCREEN);
   BitBlt(hMemDC, 0, 0, lWidth, lHeight, hDC, x, y, SRCCOPY);

   // Need to also copy bfHeader & biHeader bytes somehow...
   screen_bytes = new BYTE[screen_bytes_size];
   std::copy(sb, sb + screen_bytes_size, screen_bytes);

   DeleteDC(hMemDC);
   ReleaseDC(NULL, hDC);
   DeleteObject(hBitmap);
}

Моя конкретная проблема c заключается в том, что мне нужно сохранить bfHeader и biHeader в байтовом массиве (чтобы потом я мог сохранить изображение в виде файла) ... Так что это проблемная область ...

// Need to also copy bfHeader & biHeader bytes somehow...
screen_bytes = new BYTE[screen_bytes_size];
std::copy(sb, sb + screen_bytes_size, screen_bytes);

Как я могу также скопировать байты bfHeader и biHeader в массив?

При необходимости, вот как вы вызываете функцию ...

BYTE* screen_bytes = NULL;
DWORD screen_bytes_size = 0;
CaptureScreenIntoByteArray(screen_bytes, screen_bytes_size);

1 Ответ

3 голосов
/ 16 января 2020

Вам также нужно сделать массив достаточно большим для двух структур.

screen_bytes = new BYTE[sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + screen_bytes_size];

Затем вы можете скопировать две структуры в начало массива:

std::copy(&bfHeader, &bfHeader + 1, (BITMAPFILEHEADER*)screen_bytes);
std::copy(&biHeader, &biHeader + 1, (BITMAPINFOHEADER*)(screen_bytes + sizeof(BITMAPFILEHEADER)));

И скопируйте данные изображения после двух структур.

std::copy(sb, sb + screen_bytes_size, screen_bytes + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...