如何从像素缓冲区创建 Win32 HBITMAP
Posted
技术标签:
【中文标题】如何从像素缓冲区创建 Win32 HBITMAP【英文标题】:How to create Win32 HBITMAP from pixelbuffer 【发布时间】:2019-02-15 07:10:22 【问题描述】:我正在尝试从像素缓冲区创建一个 HBITMAP 并显示它。这是我创建 HBITMAP 的代码
char buffer[640 * 480 * 3];
memset(buffer, 255, 640 * 480 * 3);
BITMAPINFO bm = sizeof(BITMAPINFOHEADER),
640,
480, 1, 24,
BI_RGB, 640 * 480 * 3, 0, 0, 0, 0 ;
HBITMAP imageBmp = CreateDIBSection(hdc, &bm, DIB_RGB_COLORS, (void**)buffer, 0, 0);
if (imageBmp == NULL)
DWORD lastError = GetLastError();
return;
这是显示它的代码:
HDC imageDC = CreateCompatibleDC(NULL); // create an offscreen DC
SelectObject(imageDC, imageBmp); // put the loaded image into our DC
RECT rect;
GetClientRect(hDlg, &rect);
BitBlt(
hdc, // tell it we want to draw to the screen
0, 0, // as position 0,0 (upper-left corner)
rect.right - rect.left, // width of the rect to draw
rect.bottom - rect.top, // height of the rect
imageDC, // the DC to get the rect from (our image DC)
0, 0, // take it from position 0,0 in the image DC
SRCCOPY // tell it to do a pixel-by-pixel copy
);
我希望看到一个白色的图像,但我得到的是一个黑色的窗口屏幕。我很确定我的显示代码是正确的,但不知道为什么创建 HBITMAP 的代码是错误的。
【问题讨论】:
【参考方案1】:CreateDIBSection
已经通过ppvBits
参数向您返回分配的缓冲区,因此它会覆盖您的buffer
变量。来自文档(强调我的):
ppvBits 指向变量的指针,接收指向 DIB 位值的位置。
您的代码所需的修复:
删除代码以创建数组。 传递ppvBits
参数的指针地址。
仅在成功调用CreateDIBSection
之后设置像素。
char* buffer = NULL;
BITMAPINFO bm = sizeof(BITMAPINFOHEADER),
640,
480, 1, 24,
BI_RGB, 640 * 480 * 3, 0, 0, 0, 0 ;
HBITMAP imageBmp = CreateDIBSection(hdc, &bm, DIB_RGB_COLORS, (void**) &buffer, 0, 0);
if (imageBmp == NULL)
DWORD lastError = GetLastError();
return;
memset(buffer, 255, 640 * 480 * 3);
注意:
确保在生产代码中,通过将位图宽度与下一个 DWORD
边界对齐来正确计算大小,如文章“DIBs and Their Use”中所述:
计算位图的大小并不难:
biSizeImage = ((((biWidth * biBitCount) + 31) & ~31) >> 3) * biHeight
位图的疯狂四舍五入和移位 在每条扫描线的末尾以 DWORD 对齐。
在您的示例中,640 * 480 * 3
给出正确的结果只是因为640
的宽度已经可以被 4 整除。对于641
的宽度,您的公式将失败,而文章中引用的公式将给出结果正确。
【讨论】:
扫描线双字对齐? @Anders 好建议,有时间我会补充的。 嗨@zett42,感谢您的帖子。但是,它似乎不起作用。 CreateDIBSection之后,buffer还是0以上是关于如何从像素缓冲区创建 Win32 HBITMAP的主要内容,如果未能解决你的问题,请参考以下文章
从 Win32 项目中的 *.bmp 文件加载 HBITMAP
用C++在Win32中用LoadImage()绘制HBITMAP的二维数组