Контекст: я пытаюсь сделать снимок экрана с другим окном, чтобы передать его в OpenCV. В Интернете я нашел некоторый код, который должен быть в состоянии преобразовать BITMAP во что-то, с чем OpenCV может работать. К сожалению, я столкнулся с некоторыми проблемами.
Вопрос: почему атрибут / член bmBits всегда равен нулю? (Я тоже пробовал с PrintWindow вместо BitBlt результат был тот же)
#include <iostream>
#include <string>
#include <Windows.h>
int main(int argc, char* argv[])
{
std::wstring windowName = L"Calculator";
RECT rect;
HWND hwnd = FindWindow(NULL, windowName.c_str());
if (hwnd == NULL)
{
return 0;
}
GetClientRect(hwnd, &rect);
HDC hdcScreen = GetDC(NULL);
HDC hdc = CreateCompatibleDC(hdcScreen);
HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen,
rect.right - rect.left, rect.bottom - rect.top);
SelectObject(hdc, hbmp);
PrintWindow(hwnd, hdc, PW_CLIENTONLY);
BITMAP bmp;
GetObject(hbmp, sizeof(BITMAP), &bmp);
return 0;
}
bmBits
элемент не является нулевым для разделов DIB. Для зависящих от устройства растровых изображений (например, создаваемых вами) bmBits
не установлен, поскольку пиксели находятся на видеокарте, а не в основной памяти.
В вашем примере вам нужно изменить CreateCompatibleBitmap
в CreateDIBSection
если вы хотите прямой доступ к битам.
Просто для информации.
При загрузке растрового изображения из файла и хотите использовать BITMAP .bmBits (за glTexImage2D, glDrawPixels):
LoadImage(NULL, "path_to.bmp", IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE);
вы должны указать флаг LR_CREATEDIBSECTION
HBITMAP hBmp = NULL;
BITMAP BMp;
hBmp = (HBITMAP) LoadImage(NULL, "bitmap.bmp", IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
GetObject(hBmp, sizeof(BMp), &BMp);
//BMp.bmBits now points to data
От GetObject документация по MSDN. Пожалуйста, обратите внимание на второй абзац.
Если hgdiobj дескриптор растрового изображения, созданного путем вызова CreateDIBSection, и указанный буфер достаточно велик, GetObject функция возвращает
DIBSECTION
состав. В дополнение bmBits членBITMAP
структура, содержащаяся вDIBSECTION
будет содержать указатель на битовые значения битовой карты.Если hgdiobj является дескриптором растрового изображения, созданного любым другим способом, GetObject возвращает только ширину, высоту и информацию о формате цвета растрового изображения. Вы можете получить битовые значения растрового изображения, вызвав GetDIBits или же GetBitmapBits функция.
Одна вещь, которую вы могли бы сделать, это посмотреть на возвращаемое значение GetObject. Если 0, то вы знаете, что что-то пошло не так. Что-то не так с параметрами вызова.