【问题标题】:Colors are not being correctly displayed颜色未正确显示
【发布时间】:2015-11-23 15:00:06
【问题描述】:

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

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

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

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 次。

我卡住了!提前致谢。

【问题讨论】:

  • 您是否有关于从指纹读取器获得的像素数据格式的更具体信息?例如,您能否提供第一行像素的十六进制转储?如果您只是将 DIB 绘制到窗口 DC,则也不需要兼容的位图;您可以在兼容的 DC 中选择与设备无关的 HBITMAP,它应该可以完美运行。

标签: winapi gdi


【解决方案1】:

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

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

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

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

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;
}

【讨论】:

    猜你喜欢
    • 2011-08-06
    • 2012-09-30
    • 2012-12-27
    • 1970-01-01
    • 2012-01-17
    • 2016-07-24
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多