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
имеет разные размеры или формат пикселя.