Почему GetObject возвращает BITMAP с нулевыми bmBits?
Контекст: я пытаюсь сделать снимок экрана из другого окна, чтобы передать его в OpenCV. Я нашел код в Интернете, который должен иметь возможность конвертировать BITMAP в то, с чем может работать OpenCV. К сожалению, я столкнулся с некоторыми проблемами.
Вопрос: Почему атрибут bmBits/член всегда имеет значение null? (Я также попытался с 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;
}
Ответы
Ответ 1
Элемент bmBits
не равен null для разделов DIB. Для зависимых от устройства растровых изображений (например, тот, который вы создаете), bmBits
не установлен, поскольку пиксели находятся на видеокарте, а не в основной памяти.
В вашем примере вам нужно изменить CreateCompatibleBitmap
на CreateDIBSection
, если вы хотите получить прямой доступ к битам.
Ответ 2
Просто для информации.
При загрузке растрового изображения из файла и хотите использовать BITMAP .bmBits (для glTexImage2D, glDrawPixels):
LoadImage(NULL, "path_to.bmp", IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE);
u должен указывать флаг 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
Ответ 3
От GetObject документация по MSDN. Обратите внимание на второй абзац.
Если hgdiobj является дескриптором растрового изображения, созданного при вызове CreateDIBSection, и указанный буфер достаточно велик, функция GetObject возвращает структуру DIBSECTION
. Кроме того, член bmBits структуры BITMAP
, содержащийся в DIBSECTION
, будет содержать указатель на битовые значения бит.
Если hgdiobj является дескриптором растрового изображения, созданного любым другим способом, GetObject возвращает только информацию о ширине, высоте и цветовом формате растрового изображения. Вы можете получить битовые значения битмапа, вызвав функцию GetDIBits или GetBitmapBits.
Ответ 4
Одна вещь, которую вы могли бы сделать, - посмотреть на возвращаемое значение GetObject. Если 0, вы знаете, что что-то пошло не так. Что-то не так с параметрами вызова.