如何更高效检测32bpp DDB位图是否包含有效Alpha通道?
区分32bpp HBITMAP是0RGB还是ARGB格式的优化方法探讨
Windows GDI的HBITMAP对象没有专门标记是否包含有效Alpha通道的标志。我们可以通过GetObject()函数获取BITMAP结构,利用其中的bmBitsPixel字段先排除掉低于32bpp的位图格式——这类格式本身无法包含Alpha通道。
当bmBitsPixel == 32时,位图存在两种可能的格式:0RGB(所有像素的Alpha通道值为0)或ARGB(至少有一个像素的Alpha值非零)。目前我知道的唯一区分方法是检查像素中是否存在非零Alpha值(若有错误请指正):只要有一个像素的Alpha值不为0,Windows就会将该位图视为ARGB格式。
这个判定结果对ICON处理以及DrawIcon()、DrawIconEx()等函数的行为影响很大。这些函数会根据特定标志,结合图标颜色位图的格式(0RGB或ARGB),决定是否忽略或是使用包含整个图标透明数据的单色掩码ICONINFO.hbmMask。
下面的代码通过将DDB位图缩至1x1px并检测该像素是否存在非零Alpha值,来判断位图属于0RGB还是ARGB格式:
BOOL HasAlpha(HBITMAP hBmp) { BOOL res = FALSE; BITMAP bmp = {0}; GetObject(hBmp, sizeof(BITMAP), &bmp); if (bmp.bmBitsPixel == 32) { HDC hDCsrc = CreateCompatibleDC(0); HBITMAP hBmpOldSrc = (HBITMAP)SelectObject(hDCsrc, hBmp); HDC hDCdst = CreateCompatibleDC(hDCsrc); HBITMAP hBmpDst = CreateCompatibleBitmap(hDCsrc, 1, 1); HBITMAP hBmpOldDst = (HBITMAP)SelectObject(hDCdst, hBmpDst); PDWORD pPixel; SetStretchBltMode(hDCdst, STRETCH_ORSCANS); //STRETCH_ANDSCANS StretchBlt(hDCdst, 0, 0, 1, 1, hDCsrc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); if (pPixel = (PDWORD)GetBMBits(hDCdst, DIB_RGB_COLORS)) { if (*pPixel & 0xFF000000) res = TRUE; _aligned_free(pPixel); } SelectObject(hDCsrc, hBmpOldSrc); DeleteObject(SelectObject(hDCdst, hBmpOldDst)); DeleteDC(hDCsrc); DeleteDC(hDCdst); } return res; } LPVOID GetBMBits(HDC hDC, UINT usage) //使用完毕后必须用_aligned_free()释放结果,usage参数为DIB_RGB_COLORS或DIB_PAL_COLORS { LPVOID pMem = NULL; BITMAPINFO BmpInf[2]; BmpInf[0].bmiHeader.biBitCount = 0; BmpInf[0].bmiHeader.biSize = sizeof(BITMAPINFOHEADER); HBITMAP hBmp = HBITMAP(SelectObject(hDC, CreateCompatibleBitmap(hDC, 0, 0))); //取出DC中当前的位图 if (GetDIBits(hDC, hBmp, 0, 1, NULL, &BmpInf[0], usage)) { if (pMem = _aligned_malloc(BmpInf[0].bmiHeader.biSizeImage, sizeof(DWORD))) { if (!GetDIBits(hDC, hBmp, 0, BmpInf[0].bmiHeader.biHeight, pMem, &BmpInf[0], usage)) { _aligned_free(pMem); pMem = NULL; } } } DeleteObject(SelectObject(hDC, hBmp)); return pMem; }
已知将DDB的像素数据读取到用户态的成本较高,请问是否存在更优的分类方法?
内容的提问来源于stack exchange,提问作者George Robinson
相关产品推荐
相关产品推荐

