我尝试从像素缓冲区创建一个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的代码错误。
答案 0 :(得分: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
的宽度,您的公式将失败,而引用的公式从文章中得出正确的结果。