【发布时间】:2012-01-29 05:44:58
【问题描述】:
我正在尝试使用 GetDIBits 函数获取位图的像素。由于我没有研究过 Windows GDI/API,我对第一个论点 HDC 非常不确定。我在 SO 和网络上搜索了无数帖子,但无法找到有关如何在这种特定情况下初始化 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 );
【问题讨论】:
-
我不确定我是否理解问题所在。第一个参数 (
hdc) 是一个设备上下文。当您处理WM_PAINT事件、调用GetDCfunction 或执行许多其他与GDI 相关的活动时,您会得到其中一个。该函数采用 [any] 其中之一。 -
嗯,这取决于你想用位图做什么。尽管如此,调色位图或视频适配器模式仅在上个世纪才重要。如果您没有自己的窗口,GetDesktopWindow + GetWindowDC 可以正常工作。请考虑使用 GDI+ 和 Bitmap::LockBits()。
-
@CodyGray 我没有处理事件,也没有窗口。我正在编写一个控制台应用程序,我只想打开一个文件并读取像素值。我不知道该使用哪个 HDC,我不想猜测。
-
hdc 是您要显示位图的目标。如果位图显示“你知道吗?而不是给你 RGB 值,I'm just going to give you indices into my target device's color table, and you can get the RGB values from there”,这一点很重要。
LoadImage也使用它来决定位图的颜色格式。如果你传递一个 24bpp 的设备上下文,那么你将得到一个 24bpp 的位图。 -
@RaymondChen 我很困惑。据我所知,`LoadImage` 不接受 HDC。
标签: winapi bitmap gdi hbitmap getdibits