目标是显示存储在内存缓冲区中的位图。内存缓冲区的内容与磁盘存储的 .bmp 文件相同。出于性能原因,将这些缓冲区写入磁盘然后显示它们不是一种选择。 GDI+ 也不是一个选项。目前,我可以根据需要从内存缓冲区中显示每像素 24 位的位图。但是,当我尝试显示每像素 8 位位图时,图像显示的颜色错误(即图像中的图形是可识别的;缩放比例、方向等都是正确的,但所有颜色都是错误的)。
下面是我如何初始化位图 header 结构:
bfh = *(tagBITMAPFILEHEADER*)buf1;
bih = *(tagBITMAPINFOHEADER*)(buf1+sizeof(tagBITMAPFILEHEADER));
rgb = *(RGBQUAD*)(buf1+sizeof(tagBITMAPFILEHEADER)+sizeof(tagBITMAPINFOHEADER));
bi.bmiColors[0] = rgb;
bi.bmiHeader = bih;
pPixels = (buf1+bfh.bfOffBits);
然后,我尝试了几种不同的方法来创建 HBITMAP,这里有一些:
g_hBmp = CreateDIBitmap(dcPaint, &bih, CBM_INIT, (VOID *) pPixels, &bi, DIB_RGB_COLORS);
或者:
g_hBmp = CreateDIBSection(dcPaint, &bi, DIB_RGB_COLORS, (void**) &ppvBits, NULL, 0);
SetDIBits(dcPaint, g_hBmp, 0, bih.biHeight, pPixels, &bi, DIB_RGB_COLORS);
我也试过不同的参数:
- NULL 而不是 CPaintDC 对象
- DIB_PAL_COLORS 而不是 DIB_RGB_COLORS
我已转储存储 .bmp 文件结构的内存缓冲区的内容,并验证它们与使用 LoadBitmap() 加载时正确显示的磁盘存储的 .bmp 文件相同。
要强调的是,上述方法确实适用于每像素 24 位的图像。但是,它不适用于每像素 8 位的图像。
提前致谢。
最佳答案
问题是 CreateDIBSection()
和 DIB_RGB_COLORS
需要每个像素的 RGB 值(即 24 位),而您的 8 位位图包含 8-位索引到 RGB 调色板中,该调色板存储在 bi-bmiColors
中。
因此,您可以选择在预处理步骤中将 8 位位图转换为 24 位位图 - 例如,通过为 RGB 值分配内存并在原始调色板中执行查找以填充这些值.这样您就可以使用相同的代码来显示结果。或者,您可以使用原始数据创建 HBITMAP 并将其选择到内存 DC,然后将其BitBlt()
显示到显示窗口。
除了 GDI 或 GDI+ 之外的其他选项可能是考虑 WIC(Windows 成像组件)和/或 Direct2D。
关于c++ - 使用 MFC 或 Win32 显示内存缓冲区中的所有位图类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15689815/