颜色显示不正确

Colors are not being correctly displayed

只是为了学习Windows API,我正在尝试使用我购买的廉价指纹设备。 它附带的库将指纹捕获为 256x280 像素的 8 位位图,并将原始像素存储在缓冲区中。

我正在尝试将此原始像素流复制到设备独立位图 (DIB) 中,然后尝试使用此 DIB 绘制到 window。

我设法显示了图像,但颜色都不对。这是处理绘画的一段代码。

PAINTSTRUCT ps;
HDC hdc,memDC;

HBITMAP cp_bmp;

HBITMAP di_bmp;
BITMAPINFO di_bmp_info;
void *di_bmp_data;

int ptr;
int x,y;

int aux;

ZeroMemory(&di_bmp_info,sizeof(BITMAPINFO));
di_bmp_info.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
di_bmp_info.bmiHeader.biWidth=256;
di_bmp_info.bmiHeader.biHeight=280;
di_bmp_info.bmiHeader.biPlanes=1;
di_bmp_info.bmiHeader.biBitCount=8;
di_bmp_info.bmiHeader.biCompression=BI_RGB;

hdc=BeginPaint(hwnd,&ps);

// create the DIB
di_bmp=CreateDIBSection(hdc,&di_bmp_info,DIB_RGB_COLORS,&di_bmp_data,NULL,0);

// Copy the original bitstream onto the DIB
CopyMemory(di_bmp_data,fingerprint,256*280);

// create the mem dc
memDC=CreateCompatibleDC(hdc);

// create the DDB
cp_bmp=CreateCompatibleBitmap(hdc,256,280);
SelectObject(memDC,cp_bmp);

SetDIBits(memDC,cp_bmp,0,280,di_bmp_data,&di_bmp_info,DIB_RGB_COLORS);
BitBlt(hdc,10,10,256,280,memDC,0,0,SRCCOPY);
DeleteObject(cp_bmp);   
EndPaint(hwnd,&ps);

奇怪的是,当我将 di_bmp_info.bmiHeader.biBitCount 更改为 32 时,颜色显示完美,但图像尺寸变小并且水平重复大约 5 或 6 次。

我卡住了!提前致谢。

简而言之,您有一个索引位图(每个像素不是 RGB 值,而是对定义的颜色调色板的索引)并且您没有提供调色板供其使用。

BITMAPINFO 是一个可变大小的结构 - 一个 BITMAPINFOHEADER,后跟至少一个但可能更多的 RGBQUAD 结构。对于索引位图深度(8 bpp 及以下),需要在内存中的 BITMAPINFOHEADER 之后提供一个调色板。

所需的调色板条目数由 biBitCountbiClrUsed 字段确定。如果 biClrUsed 为 0,则调色板条目数必须为 1 << biBitCount,或者在 8bpp 的情况下为 256。如果位图不需要它们,将 biClrUsed 设置为 0 以外的值可以让您提供更少的调色板条目。

因为您还没有设置 biClrUsed 一个完整的 256 调色板被假定为遵循内存中的 BITMAPINFOHEADER 并且基本上使用随机内存。

BITMAPINFO 仅提供一个 RGBQUAD 本身,因此您需要扩展结构以提供其余部分,例如:

struct MyBitmapInfo
{
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD palette[256];
};

您实际上从哪里获得调色板取决于您,但是您可以使用这样的灰度调色板:

struct MyBitmapInfo di_bmp_info;

ZeroMemory(&di_bmp_info,sizeof(struct MyBitmapInfo));
di_bmp_info.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
di_bmp_info.bmiHeader.biWidth=256;
di_bmp_info.bmiHeader.biHeight=280;
di_bmp_info.bmiHeader.biPlanes=1;
di_bmp_info.bmiHeader.biBitCount=8;
di_bmp_info.bmiHeader.biCompression=BI_RGB;

// initialise greyscale palette
for (int i = 0; i < 256; i++)
{
    di_bmp_info.palette[i].rgbRed =
    di_bmp_info.palette[i].rgbGreen =
    di_bmp_info.palette[i].rgnBlue = i;
}