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

C++ 使用MFC或Win32显示内存缓冲区中的所有位图类型,c++,winapi,graphics,mfc,bitmap,C++,Winapi,Graphics,Mfc,Bitmap,目标是显示存储在内存缓冲区中的位图。内存缓冲区的内容与磁盘存储的.bmp文件相同。出于性能原因,将这些缓冲区写入磁盘然后显示它们不是一个选项。GDI+也不是一个选项。目前,我可以根据需要显示内存缓冲区中的每像素24位位图。但是,当我尝试显示8位/像素位图时,图像显示的颜色错误(即图像中的图形可识别;缩放、方向等正确,但所有内容都是错误的颜色) 下面是初始化位图头结构的方法: bfh = *(tagBITMAPFILEHEADER*)buf1; bih = *(tagBITMAPINFOHEADE

目标是显示存储在内存缓冲区中的位图。内存缓冲区的内容与磁盘存储的.bmp文件相同。出于性能原因,将这些缓冲区写入磁盘然后显示它们不是一个选项。GDI+也不是一个选项。目前,我可以根据需要显示内存缓冲区中的每像素24位位图。但是,当我尝试显示8位/像素位图时,图像显示的颜色错误(即图像中的图形可识别;缩放、方向等正确,但所有内容都是错误的颜色)

下面是初始化位图头结构的方法:

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);
或:

我还尝试了不同的参数:

  • NULL而不是CPaintDC对象
  • DIB_PAL_颜色而不是DIB_RGB_颜色
我已经转储了存储.bmp文件结构的内存缓冲区的内容,并验证了它们与磁盘存储的.bmp文件完全相同,这些文件在加载LoadBitmap()时正确显示

要强调的是,上述方法确实适用于每像素24位的图像。但是,它不适用于每像素8位的图像


提前感谢。

问题在于
CreateDIBSection()
with
DIB\u RGB\u COLORS
需要每个像素的RGB值(即24位),而您的8位位图包含的像素是RGB调色板中的8位索引,该调色板存储在
bi-COLORS

因此,您可以选择在预处理步骤中将8位位图转换为24位—例如,为RGB值分配内存,并在原始调色板中执行查找以填充这些值。这样,您就可以使用相同的代码来显示结果。或者,您可以使用原始数据创建HBITMAP,并将其选择到内存DC中,然后将其显示到显示窗口中


除了GDI或GDI+之外,其他选项可能会考虑WIC(Windows成像组件)和/或DICT2D2.

< P>汉斯说“代码> BI”是正确的。BMICROLOR 没有正确处理。不要直接处理
bi.bmiColors
表,只需将
pBitmapInfo
指向
BITMAPFILEHEADER
中的适当偏移量并强制转换即可。这会自动处理颜色表。是的,
pBitmapInfo
pBitmapInfoHeader
确实指向同一个位置;他们所指的在每种情况下都是不同的。
CreateDIBitmap()
函数需要这两个指针

pBitmapFileHeader = (LPBITMAPFILEHEADER)buf1;
pBitmapInfoHeader = (LPBITMAPINFOHEADER)(buf1+sizeof(BITMAPFILEHEADER));
pBitmapInfo = (LPBITMAPINFO)(buf1+sizeof(BITMAPFILEHEADER));
pPixels = (buf1+pBitmapFileHeader->bfOffBits);
然后在OnPaint()中执行以下操作:


您没有正确对待bi.BMI颜色。它不是指针,而是一个表。您必须复制表内容。并确保BITMAPINFO足够大,可以存储它。
pBitmapFileHeader = (LPBITMAPFILEHEADER)buf1;
pBitmapInfoHeader = (LPBITMAPINFOHEADER)(buf1+sizeof(BITMAPFILEHEADER));
pBitmapInfo = (LPBITMAPINFO)(buf1+sizeof(BITMAPFILEHEADER));
pPixels = (buf1+pBitmapFileHeader->bfOffBits);
g_hBmp = CreateDIBitmap(dcPaint, pBitmapInfoHeader, CBM_INIT, (VOID *) pPixels, pBitmapInfo, DIB_RGB_COLORS);