GetDiBits: разные измерения передаются в BITMAPINFOHEADER

У меня есть несколько вопросов относительно GetDiBits, основанных на моем опыте работы с этой функцией. По ошибке я создал растровое изображение в два раза больше необходимого мне размера:

HBITMAP hBmpSection = CreateCompatibleBitmap(ScreenDC, 2 * radius, 2 * radius);

Я не заметил, потому что следующая часть кода работала. Я BitBlt часть экрана на половине этого растрового изображения:

bmpSmallInfo.bmiHeader.biHeight = (2*radius / 2);
bmpSmallInfo.bmiHeader.biWidth = (2*radius / 2);
BitBlt(hSectionDC, 0, 0, bmpSmallInfo.bmiHeader.biWidth, bmpSmallInfo.bmiHeader.biHeight, ScreenDC, 0, 0, SRCCOPY);

Тогда я получаю массив coresponding:

GetDIBits(hSectionDC, hBmpSection, 0, bmpSmallInfo.bmiHeader.biHeight, dataBuffer3, &bmpSmallInfo, DIB_RGB_COLORS);

Когда я отправил все эти данные на другой компьютер, изображение получилось совершенно правильным (без черных краев, как было бы в случае отправки слишком большого растрового изображения). Это означает, что GetDiBits игнорирует правильный размер растрового изображения и использует тот, который предоставлен в BITMAPINFOHEADER, без сбоев. (Я использую Win10.)

Это нормально? Поскольку я не хочу отправлять нежелательные байты по сети, я должен спросить: выводит ли GetDiBits массив с размером правильных измерений: (4*radius^2)*3 или он присматривает за значениями из структуры: радиус ^2 *3 - игнорирующая прокладка-?

2 ответа

Решение

В основном у вас есть такой код:

hbitmap = CreateCompatibleBitmap(hdc, max_width, max_height);
oldbmp = (HBITMAP)SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, width, height, hdc, x, y, SRCCOPY);
SelectObject(memdc, oldbmp);
int size = width_in_bytes_with_padding * height;
allocate size count memory ...
BITMAPINFOHEADER bi = { 40, width, height, 1, 24, BI_RGB };
GetDIBits(...);

Вопрос, который вы, похоже, задаете: нормально ли это, если width/height меньше чем max_width/max_height?

Ответ - да. GetDIBits надеется dataBuffer3 быть достаточно большим, чтобы получить size байт. width/height должно быть меньше или равно max_width/max_height

Обратите внимание, что BitBlt это самая медленная функция в этом коде, это то, что вам нужно оптимизировать. CreateCompatibleBitmap занимает несколько микросекунд, вы не сэкономите много, создав большую картинку.

GetDIBits - довольно странная функция по стандартам GDI. Вместо обычной схемы принятия либо просто HDC или HBITMAP он хочет и того, и накладывает дополнительные ограничения на HBITMAP параметр. iirc Этот шаблон используется, когда вы просите GDI (потенциально) преобразовать растровое изображение относительно таблицы цветов - т.е. в 8-битных или более низких изображениях вы должны выбрать HPALETTE в HDC,

Страница функции GetDIBits на MSDN, однако, довольно ясна - LPBITMAPINFO Параметр:

Указатель на структуру BITMAPINFO, которая указывает желаемый формат для данных DIB.

Последующие комментарии уточняют, что если lpvBits NULL, вы можете использовать GetDIBits для получения растровых свойств, записав их в BITMAPINFO состав.

Ответить на ваш конкретный вопрос; GetDIBits выводит в dataBuffer, используя размеры и формат, который вы предоставляете в BITMAPINFOHEADER и будет обрезать и трансформировать при необходимости, если DDB имеет разные размеры или формат пикселя.

Другие вопросы по тегам