【发布时间】:2015-06-07 07:38:51
【问题描述】:
我一直在尝试从文件加载 16 位 (A1R5G5B5) BMP 并将其 alpha 通道用作位掩码。除了过去一周一直困扰我的一个问题外,我一切都正常工作。就是当我使用 CreateDIBitmap 来制作带有字节缓冲区的 1 位通道时,所创建的位图仅在第一次绘制时才使用其所有位的倒数。在下一次绘画中,位正确地翻转到提供的数据,并在之后的所有绘图中保持这种状态。这种行为非常奇怪,并且发生在所有 Windows 版本上,我已经追踪到它与 HDC 的某种设置以及可能的 CreateDIBitmap 有关。我已经尝试了很多事情,包括将 HDC 前后的前景色和背景色设置为许多值,但我尝试过的一切仍然保持这种行为。
这是一个可以尝试的 POC:
BITMAPINFOHEADER bmih;
BITMAPINFO bmi;
HBITMAP mask;
PBYTE data;
PBYTE alpha;
SIZE dimension;
void WhenCreated() // WM_CREATE
{
dimension.cx=3;
dimension.cy=1;
alpha=(PBYTE)malloc(1);
data=(PBYTE)malloc(1);
alpha[0]=0xA0; // 0b10100000
}
#define BIN_SCAPE(B,A) (B[0]&(1<<A))?1:0
void WhenPresenting(HDC H) // WM_PAINT
{
printf(
"ALPHA:\t%i %i %i\n",
BIN_SCAPE(alpha,7),
BIN_SCAPE(alpha,6),
BIN_SCAPE(alpha,5)
);
HDC memory;
HBITMAP matter;
memory=CreateCompatibleDC(NULL);
memset(&bmi,0x0,sizeof(BITMAPINFO));
bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth=dimension.cx;
bmi.bmiHeader.biHeight=dimension.cy;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=1;
bmi.bmiHeader.biCompression=BI_RGB;
memset(&bmih,0x0,sizeof(BITMAPINFOHEADER));
bmih.biSize=sizeof(BITMAPINFOHEADER);
bmih.biWidth=bmi.bmiHeader.biWidth;
bmih.biHeight=bmi.bmiHeader.biHeight;
mask=CreateDIBitmap(
memory,
&bmih,
CBM_INIT,
alpha,
&bmi,
DIB_RGB_COLORS
);
SelectObject(memory,mask);
GetDIBits(memory,mask,0,1,data,&bmi,DIB_RGB_COLORS);
printf(
"DATA:\t%i %i %i\n",
BIN_SCAPE(data,7),
BIN_SCAPE(data,6),
BIN_SCAPE(data,5)
);
StretchBlt(
H,
0,0,128,128,
memory,
0,0,dimension.cx,dimension.cy,
SRCCOPY
);
DeleteDC(memory);
DeleteObject(mask);
}
当程序加载显示的数据与给定的相反时,随后的绘制会导致数据与控制台输出中提供的数据相匹配,肯定会发生位翻转。我的猜测是提供的第一个 HDC 可能使用与第一个之后的所有调色板不同的调色板,这会导致这种行为?
【问题讨论】: