如何将像素数组转换为HBITMAP
How to convert an Array of pixels to HBITMAP
我有一个像素数组,我需要将其转换为HBITMAP以便在窗口中显示它。我试图使用CreateDIBitmap(),但我没有BMP头。我试图根据MSDN文档手动构建它们,但这不起作用。
我的代码是这样的
HBITMAP hBitmap
char pixels[160*120]; // White grayscale image of size 160x120
memset(pixels,255,sizeof(pixels));
BITMAPINFOHEADER bmih;
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = 160;
bmih.biHeight = -120;
bmih.biPlanes = 1;
bmih.biBitCount = 8;
bmih.biCompression = BI_RGB ;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 10;
bmih.biYPelsPerMeter = 10;
bmih.biClrUsed =0;
bmih.biClrImportant =0;
BITMAPINFO dbmi;
dbmi.bmiHeader = bmih;
dbmi.bmiColors->rgbBlue = 0;
dbmi.bmiColors->rgbGreen = 0;
dbmi.bmiColors->rgbRed = 0;
dbmi.bmiColors->rgbReserved = 0;
void* bits = (void*)&(pixels[0]);
hBitmap = CreateDIBitmap(localDC, &bmih, CBM_INIT, qB.bmBits, &dbmi, DIB_RGB_COLORS);
现在我得到了一个非NULL的hBitmap,这很好,但它总是显示黑色图像,好像它没有指向像素数组。我使用代码
检查它BITMAP qB;
GetObject(reinterpret_cast<HGDIOBJ>(hBitmap),sizeof(BITMAP),reinterpret_cast<LPVOID>(&qB));
确实qB。bmBits为NULL。问题是什么?如何解决?
我知道怎么做了。我们需要用CreateDIBSection()
代替CreateDIBitmap()
下面是工作代码
HBITMAP hBitmap = NULL;
unsigned char pixels[160*120*3];
for (int i=0; i<160*120*3; i++){
pixels[i] = (i%4==1)*255; // An BGR (not RGB) 160x120 image.
}
BITMAPINFOHEADER bmih;
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = 160;
bmih.biHeight = -120;
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB ;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 10;
bmih.biYPelsPerMeter = 10;
bmih.biClrUsed =0;
bmih.biClrImportant =0;
BITMAPINFO dbmi;
ZeroMemory(&dbmi, sizeof(dbmi));
dbmi.bmiHeader = bmih;
dbmi.bmiColors->rgbBlue = 0;
dbmi.bmiColors->rgbGreen = 0;
dbmi.bmiColors->rgbRed = 0;
dbmi.bmiColors->rgbReserved = 0;
void* bits = (void*)&(pixels[0]);
// Create DIB
hBitmap = CreateDIBSection(localDC, &dbmi, DIB_RGB_COLORS, &bits, NULL, 0);
if (hBitmap == NULL) {
::MessageBox(NULL, __T("Could not load the desired image image"), __T("Error"), MB_OK);
return;
}
// copy pixels into DIB.
memcpy(bits,pixels,sizeof(pixels));
对于灰度级图像,在循环中将像素复制到DIB,而不是使用memcpy()
#define INTENSITY unsigned char
INTENSITY* dest = (INTENSITY*)bits;
const INTENSITY* src = .. Put your char array of pixels;
for (int j=0; j<imageWidth; j++){
for (int i=0; i<imageHeight; i++, src++){
*dest++ = *src;
*dest++ = *src;
*dest++ = *src;
}
// Padd the line to round WORD.
if (imageWidth%2)
*dest++ = 0;
}
你的帖子很有帮助(答案),但它不适合我,这里是代码与小更正:
// creating input
unsigned char pixels[160*120*3];
for (int i=0; i<160*120*3; i++)
pixels[i] = (i%4==1)*255; // An BGR (not RGB) 160x120 image.
// at this point we have some input
BITMAPINFOHEADER bmih;
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = 160;
bmih.biHeight = -120;
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB ;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 10;
bmih.biYPelsPerMeter = 10;
bmih.biClrUsed =0;
bmih.biClrImportant =0;
BITMAPINFO dbmi;
ZeroMemory(&dbmi, sizeof(dbmi));
dbmi.bmiHeader = bmih;
dbmi.bmiColors->rgbBlue = 0;
dbmi.bmiColors->rgbGreen = 0;
dbmi.bmiColors->rgbRed = 0;
dbmi.bmiColors->rgbReserved = 0;
HDC hdc = ::GetDC(NULL);
HBITMAP hbmp = CreateDIBitmap(hdc, &bmih, CBM_INIT, pixels, &dbmi, DIB_RGB_COLORS);
if (hbmp == NULL) {
::MessageBox(NULL, L"Could not load the desired image image", L"Error", MB_OK);
return;
}
::ReleaseDC(NULL, hdc);
// a little test if everything is OK
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hbmp);
CloseClipboard();
// cleanup
DeleteObject(hbmp);
这里的其他答案非常有用,但我最终只用了一行就能实现它。
HBITMAP hBm = CreateBitmap(width,height,1,32,pixels); // 1 plane, 32 bits
希望对将来的读者有帮助。
此外,如果您需要使用设备上下文,还有CreateCompatibleBitmap
和SetDIBits
。
CreateDIBitmap
的MSDN上写着:
使用fdwInit作为CBM_INIT调用CreateDIBitmap相当于调用CreateCompatibleBitmap函数在设备的格式,然后调用SetDIBits函数来将DIB位转换为DDB。
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将 win32 hbitmap 转换为 winrt softwarebitmap
- 将位数组转换为 HBITMAP 后 bmBits 的 NULL 指针
- MFC如何将带有透明属性的PNG转换为HBITMAP
- Hbitmap/BITMAP转换成.bmp文件
- GDI C/ c++ - BITMAP转换成现有的HBITMAP
- 如何将像素数组转换为HBITMAP
- 将HBITMAP转换为cv::Mat
- 从HBITMAP转换到IWICBitmap
- 将BITMAP转换为HBITMAP
- 如何将HBITMAP转换为JNI的BYTE数组