16 位桌面颜色深度中的 BitBlt + UpdateLayeredWindow 和 CreateDIBSection
Posted
技术标签:
【中文标题】16 位桌面颜色深度中的 BitBlt + UpdateLayeredWindow 和 CreateDIBSection【英文标题】:BitBlt + UpdateLayeredWindow and CreateDIBSection in 16-bit desktop color depth 【发布时间】:2011-03-20 08:26:11 【问题描述】:我在客户区有一个透明背景的应用程序,它被绘制为黑色,因为窗口没有分层。在它的每个 WM_PAINT 消息中,我对内存 DC 执行 BitBlt,之后我使用带有 UpdateLayeredWindow 的内存 DC 到分层画布窗口。
内存-DC的设置:
HDC hdcMemory = CreateCompatibleDC(NULL);
HBITMAP bmpMemory = CreateDIBSection(hdcMemory, (BITMAPINFO*)&m_BitmapInfoHeader,
DIB_RGB_COLORS, (void **)&m_pDIBSectionBits, NULL, (DWORD)0);
SelectObject(hdcMemory, bmpMemory);
在 WM_PAINT 中,我使用 BitBlt 函数将应用程序客户区 DC 信息复制到内存 DC。之后,我将使用内存 DC 执行 UpdateLayeredWindow 到分层画布窗口 DC(它的 CWnd)。所以它是实时的,结果是:我有一个正常的应用程序窗口和一个分层的窗口,除了不规则的形状和每像素的透明度。
在 32 位桌面颜色深度下一切正常!如果我切换到 16 位,分层画布窗口就会变得混乱。绘图看起来很糟糕,整个窗口都可以点击。
它认为是因为缺少 alpha 通道信息。
所以我在谷歌上搜索了很多解决方案。我发现在这种情况下,我必须使用
创建 memory-DCHDC hdcMemory = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
而不是 CreateCompatibleDC(NULL)。因为兼容的 DC 会给我一个 16 位的 DC。
使用 CreateDC 绘图效果更好。但是整个窗口仍然是可点击的,并且在分层窗口中透明度被绘制为黑色。
所以我认为问题出在 BitBlt 或 CreateDIBSection 的 BitmapInfoHeader 上。
不知道是用 BitmapInfoHeader.biBitCount = 32 还是 BitmapInfoHeader.biBitCount = 16 位。认为它是 32。那么 biCompression -> BI_RGB 或 BI_BITFIELDS 呢?
如何在 BitBlt(..., SRCCOPY) 16 位 DC 到 memory-DC 之后将 alpha 通道信息添加到 memory-DC,以便它与 UpdateLayeredWindow 一起使用? (也许:将 rgb 通道与 alpha 通道预乘?)不知道该怎么做。
我稍微接近了 16 位桌面颜色深度问题。
HDC hdcMemory = CreateCompatibleDC(NULL);
上述方法似乎有效。但是我的 UpdateLayeredWindow 函数产生的结果看起来很乱。
所以,这是因为缺少黑色!每个全黑的像素都变得透明。您可以查看并单击。所有其他像素都失去了黑色部分,只能点击。
我做了一个测试:我打开了Windows Paint.exe,做了一个windows宽高和黑色作为填充颜色的表面。
然后我把它放在我的分层窗口下(缺少黑色),再次将分层窗口作为前景窗口,ta-da,我的分层窗口与通过 Paint.exe 黑色像素的闪耀结合看起来很正常。
所以我用 BitBlt 过期了,它又是光栅操作参数。但没有运气。
如何在使用 UpdateLayeredWindow 绘图之前将黑色与 BitBlt 混合到我的 DC 中?
【问题讨论】:
【参考方案1】:看看这里: http://msdn.microsoft.com/en-us/library/aa453651.aspx 我确信,这是一个光栅操作问题。
【讨论】:
以上是关于16 位桌面颜色深度中的 BitBlt + UpdateLayeredWindow 和 CreateDIBSection的主要内容,如果未能解决你的问题,请参考以下文章
求单色位图,16色位图,24色位图和256色位图之间的区别?
图像位深度 8位 16位 24位 32位区别对比 RGB 真彩色 基本概念:(大小,深度,通道)位深度数据类型转换原理 Mat数据读取(opencv里的imread)