c++ - 使用 MFC 或 Win32 显示内存缓冲区中的所有位图类型

标签 c++ winapi graphics mfc bitmap

目标是显示存储在内存缓冲区中的位图。内存缓冲区的内容与磁盘存储的 .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/

相关文章:

c++ - 如何破解虚拟表?

winapi - Richedit 2.0 在 WM_SETTEXT 后撤消

c++ - 如何在 Visual Studio 2012 中为基于 Win32 对话框的应用程序启用 'Insert Activex Control'?

c# - 自定义绘制下拉面板在控制范围之外

c++ - 来自通用命名空间的前向声明类(在 std::hash 中

c++ - C++ 编译器如何优化模板代码?

c++ - 为 C++ 示例设置基本 Esent

android - 为什么文档样本除以2来计算位图加载的inSampleSize?

objective-c - 连接两个 NSBezierPath

c++ - CGAL:正常和加权 3D 三角剖分之间的区别