目标是显示存储在内存缓冲区中的位图。内存缓冲区的内容与磁盘存储的.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);
或者:
g_hBmp = CreateDIBSection(dcPaint, &bi, DIB_RGB_COLORS, (void**) &ppvBits, NULL, 0);
SetDIBits(dcPaint, g_hBmp, 0, bih.biHeight, pPixels, &bi, DIB_RGB_COLORS);
我也尝试了不同的参数:
我已经转储了存储.bmp文件结构的内存缓冲区的内容,并验证它们与加载LoadBitmap()时正确显示的磁盘存储的.bmp文件相同。
要强调的是,上述方法适用于每像素24位图像。但是,它不适用于每像素8位图像。
提前致谢。
答案 0 :(得分:1)
问题是CreateDIBSection()
DIB_RGB_COLORS
期望每个像素(即24位)的RGB值,而您的8位位图包含8位索引到RGB调色板的像素,存储在bi-bmiColors
。
因此,您可以选择在预处理步骤中将8位位图转换为24位 - 例如,为RGB值分配内存并在原始调色板中执行查找以填充这些值。这样您就可以使用相同的代码来显示结果。或者,您可以使用原始数据创建HBITMAP并将其选择到内存DC中,然后BitBlt()
将其选择到显示窗口。
除了GDI或GDI +之外,其他选项可能是考虑WIC(Windows Imaging Component)和/或Direct2D。
答案 1 :(得分:0)
汉斯说bi.bmiColors
未被正确对待是正确的。不要直接处理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()中执行:
g_hBmp = CreateDIBitmap(dcPaint, pBitmapInfoHeader, CBM_INIT, (VOID *) pPixels, pBitmapInfo, DIB_RGB_COLORS);