我试图使用GetDIBits函数获得位图的像素。由于我没有研究过Windows GDI/API,所以我对第一个参数HDC非常不确定。我在SO和web上搜索了无数的帖子,但无法找到关于如何在这种特定情况下初始化HDC的信息或示例。以下是我读取像素值的过程:
HBITMAP hBitmap = (HBITMAP) LoadImage(0, L"C:/tmp/Foo.bmp" ,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
// check hBitmap for error
BITMAP bm;
::GetObject( hBitmap , sizeof(bm) , &bm );
// TODO: GetDIBits()
解决方案:
在浏览了更多的网页后,我已经能够拼凑出以下内容:
/* Omitting error checks for brevity */
HDC dcBitmap = CreateCompatibleDC ( NULL );
SelectObject( dcBitmap, hBitmap );
BITMAPINFO bmpInfo;
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = bm.bmWidth;
bmpInfo.bmiHeader.biHeight = -bm.bmHeight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = 0;
COLORREF* pixel = new COLORREF [ bm.bmWidth * bm.bmHeight ];
GetDIBits( dcBitmap , hBitmap , 0 , bm.bmHeight , pixel , &bmpInfo , DIB_RGB_COLORS );
源位图通常是与设备相关的位图。虽然不太常见的现在,这可能意味着,位图的像素值被存储为索引颜色表。在这些情况下,GetDIBits需要访问存储在设备上下文中的颜色表。
如果你的位图使用RGB值而不是索引,那么设备上下文应该是无关紧要的,尽管在我的经验中,你仍然必须提供一个有效的(参见什么是HDC在GetDIBits?),也许它会考虑设备上下文的其他方面,如颜色深度。
您的目标是获得像素颜色值,还是调用GetDIBits
?如果你只是想要像素内容,你可以使用GetObject
来获得BITMAP
结构对应于你的HBITMAP
句柄,bmBits
指针在该结构给予访问像素(注意:它将在位图的原始格式,这可能不是24bpp,所以检查结构的其他字段,看看格式是什么)。