Копирование из упакованного пустого указателя DIB

Я работаю над API для кэширования объектов GDI, написанных на C ++, в котором я реализую различные методы Create, имитирующие API win32. Одним из таких методов является CreateDIBPatternBrushPt(), который принимает в VOID* в упакованный DIB. VOID* содержит BITMAPINFO за структурой сразу следует массив байтов, определяющих пиксели растрового изображения. Я провел некоторое исследование на упакованных DIB. Согласно книге «Программирование Windows», как и в Википедии, длина равна произведению длины строки и biHeight (член BITMAPINFOHEADER), где:

RowLength = 4 * ((bmi.bcWidth * bmi.bcBitCount + 31) / 32) ;

Итак, в настоящее время я думаю сделать что-то вроде этого:

//copy BIMAPINFO to access width and height
//lpPackedDIB is the VOID* parameter of CreateDIBPatternBrushPt()
BITMAPINFO tmpBitmapInfo;
std::memcpy(&tmpBitmapInfo, lpPackedDIB, sizeof(BITMAPINFO));

//copy entire packed DIB
int rowLength = 4 * ((tmpBitmapInfo.bmiHeader.biWidth * tmpBitmapInfo.bmiHeader.biBitCount + 31) / 32);
std::memcpy(m_pPackedDIB, lpPackedDIB, sizeof(BITMAPINFO) + rowLength * std::abs(bitmapInfo.bmiHeader.biHeight));

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

РЕДАКТИРОВАТЬ:

Рекомендации:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd183493(v=vs.85).aspx
https://en.wikipedia.org/wiki/BMP_file_format#File_structure
https://www-user.tu-chemnitz.de/~heha/petzold/ch15b.htm (в частности, раздел «Пиксельные биты DIB»)

-1

Решение

Этот ответ был опубликован ранее, но почему-то снят. Это не касается непосредственно вопроса, но дает хорошее понимание проблемы, с которой я столкнулся. Кредит пользователю: Бармак Шемирани.

Вы можете просто использовать CreatePatternBrush получить HBRUSH от HBITAMP

Или использовать CreateDIBPatternBrushPt, Тем не менее, обратите внимание, что упакованный DIB всего на 14 байтов меньше, так как это не нужно BITMAPFILEHEADER, Это делает его полезным для очень маленьких кистей. Например, 2×1 зеленая / черная кисть:

typedef struct
{
BITMAPINFOHEADER header;
unsigned char bits[2 * 1 * 4];
} DIBSTRUCT;

const DIBSTRUCT dib =
{
{ sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB, 0, 0, 0, 0, 0 },
{ 0,0xff,0,0, 0,0,0,0 }
};

HBRUSH hbrush = CreateDIBPatternBrushPt(&dib, DIB_RGB_COLORS);

Вы также можете сделать кисть из растрового файла. Выделите чур, добавьте место для BITMAPINFOHEADER и таблица цветов. Затем скопируйте BITMAPINFOHEADER, затем таблица цветов (если есть), затем пиксели. Пример:

HBRUSH getbrush(HBITMAP hbitmap)
{
BITMAP bm;
GetObject(hbitmap, sizeof(bm), &bm);

int colorCount = 0;
if (bm.bmBitsPixel == 1) colorCount = 2;
if (bm.bmBitsPixel == 4) colorCount = 16;
if (bm.bmBitsPixel == 8) colorCount = 256;

RGBQUAD rgb[256];
if (colorCount)
{
HDC memdc = CreateCompatibleDC(NULL);
HGDIOBJ oldbitmap = SelectObject(memdc, hbitmap);
GetDIBColorTable(memdc, 0, colorCount, rgb);
SelectObject(memdc, oldbitmap);
DeleteDC(memdc);
}

BITMAPINFOHEADER bminfo = { sizeof(BITMAPINFOHEADER),
bm.bmWidth, bm.bmHeight, 1, bm.bmBitsPixel, BI_RGB, 0, 0, 0, 0, 0 };
DWORD size = ((bm.bmWidth * bm.bmBitsPixel + 31) / 32) * 4 * bm.bmHeight;
char *dib = new char[sizeof(BITMAPINFOHEADER) + colorCount * 4 + size];
memcpy(dib, &bminfo, sizeof(BITMAPINFOHEADER));
memcpy(dib + sizeof(BITMAPINFOHEADER), rgb, colorCount * 4);
memcpy(dib + sizeof(BITMAPINFOHEADER) + colorCount * 4, bm.bmBits, size);
HBRUSH hbrush = CreateDIBPatternBrushPt(dib, DIB_RGB_COLORS);

//clearnup
DeleteObject(hbitmap);
delete[]dib;

return hbrush;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector