GetDIBits使用方法

最近在做一个关于远程控制的插件,结果刚开始就在获取屏幕图像并取出每个像素点的RGB色的时候就碰到了问题,以下就简单的写一个代码


HDC screenDC = CreateDC("DISPLAY", NULL, NULL, NULL);

HDC hMemDC = CreateCompatibleDC(screenDC);
//因为是获取整个桌面的图像,所以这里的x,y是事先获取到的屏幕分辨率,GetSystemMetrics可完成此功能
//两个内存对象的HDC参数要使用同一个,刚开始我使用错了,造成一直无法取得数据
HBITMAP hBitmap = CreateCompatibleBitmap(screenDC, x, y);

BITMAPINFO bitmapInfo = {0};
//BITMAPINFO结构有两个成员变量,分别是BITMAPINFOHEADER结构和RGBQUAD结构,
//BITMPINFOHEADER结构中包含了图像的一些基本信息,包括宽与高
//我们要先将biSize属性初始为BITMAPINFOHEADER结构的大小,以便GetDIBits函数在调用的时候填充其他的属性变量
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
//将hBitmap选入到hMemDC中,通俗点说就是关联起来,对hMemDC的操作也就是对hBitmap操作,
//比如在hMemDC中写入文字在hBitmap中也能体现,常见给图片打水印可以用这个方法实现
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
//StretchBlt函数,将拷贝整个屏幕的图像到hMemDC中,函数说明见MSDN,此处不详细解释
StretchBlt(hMemDC, 0, 0, x, y, screenDC, 0, 0, x, y, SRCCOPY);
//第一次调用 GetDIBits函数,并将参数五置为NULL,且bitmapInfo的BITMAPINFOHEADER结构的biSize已经初始化过,
//函数将会把图像的宽,高还有整个图像所点的字节数填充到bitmapInfo结构中,以便接下来的使用
//函数的详细解释网上很多。
GetDIBits(hMemDC, hBitmap, 0, y, NULL, &bitmapInfo, DIB_RGB_COLORS);
//根据第一次调用 GetDIBits函数完成后,填充到bitmapInfo中的图像占字节数大小来动态分配内存
//你也可以用图像的宽*高来得到图像所占字节数,但此方法有一点要说明 ,第一行的字节数必须是4的倍数,不够的用0补足。
//例:宽为923像素的图像,923/4 = 230(取整数部分),多出三个字节,这个时候我们就要补足四位,变成(230+1)*4 = 924 实际一行占的字节数
unsigned char *bitmapBits = new unsigned char[bitmapInfo.bmiHeader.biSizeImage];
memset(bitmapBits, 0, bitmapInfo.bmiHeader.biSizeImage);//初始为0
//第二次调用函数,并且第五个参数为有效的指针且可写入,
//函数调用后,将会把图像的每个像素点的RGB值 以16进制值写入到bitmapBits中,
//常见的一个像素是占4个字节,第一个字节是蓝色--B,第二个字节是绿色--G,第三个字节是红色--R,第四个不知道
GetDIBits(hMemDC, hBitmap, 0, y, bitmapBits, &bitmapInfo, DIB_RGB_COLORS);
SelectObject(hMemDC, hOldBitmap);

//然后是释放资源
delete []bitmapBits;
DeleteObject(hBitmap);
DeleteDC(hMemDC);
DeleteDC(screenDC);

大家可以再结合网上讲的一些知识点,完成自己要完成的功能,

bitmapBits保存的就是屏幕的矩阵图像数据,接下来就是压缩传输了或者根据BMP文件的格式保存成一张图片。

你可能感兴趣的:(C++)