Windows核心编程_获取鼠标指定位置的RGB颜色值

Windows核心编程_获取鼠标指定位置的RGB颜色值

大家平常会见到很多屏幕取色工具,其原理都是获取鼠标位置的屏幕像素点颜色!

一般思路都是:获取鼠标位置,然后取出鼠标指向的屏幕像素点颜色!

GetCursorPos函数是WindowsSDK库下的一个API函数,用于获取鼠标位于屏幕中偏移的坐标信息!

函数原型:

BOOL GetCursorPos(LPPOINT lpPoint);
参数介绍:LPPOINT lpPoint:用于接受鼠标坐标的POINT结构体指针
返回值:成功返回TRUE,失败返回FALSE!

示例:

 

POINT Mouse_X_Y;	//存放鼠标坐标结构体
	if (FALSE == GetCursorPos(&Mouse_X_Y)){	//获取鼠标坐标
		printf("error:无法获取鼠标指针位于屏幕的坐标值");
	}
	printf("鼠标的X坐标:%d,鼠标的Y坐标:%d", Mouse_X_Y.x, Mouse_X_Y.y);
	getchar();

 

运行结果:

 

 

已经可以成功知道鼠标的坐标了,那么接下来就是获取鼠标指向屏幕上的像素点信息!

首先Windows下一个窗口的绘图信息(像素点信息)都是由DC来描述的,DC指向一个绘图设备表,这个表里包含了一个窗口的所有绘图信息,比如位于屏幕上的坐标,还有坐标上的像素点信息等等!

而且我们的窗口是显示在屏幕上的,所以我们如果想取某个窗口的颜色,可以把窗口放到屏幕上,Windows会把窗口的绘图信息,呈现到屏幕的DC中去!

GetDC,可以用来获取指定程序的DC绘图设备描述符!

函数原型:

HDC GetDC(HWND hWnd);
参数介绍:HWND hWnd:	窗口句柄,NULL获取屏幕的DC句柄
返回值:窗口DC,否则返回NULL

有了窗体的绘图信息,那么怎么得到DC指向的绘图表里的绘图信息呢?


GetPixel 此函数是用来获取指定DC绘图表里的像素点

 

函数原型:

 

COLORREF GetPixel(HDC hdc, int nXPos, int nYPos);
参数介绍:
HDC hdc:DC
int nXPos:X坐标
int nYPos:Y坐标
返回值:返回DC下的RGB颜色值,注意这个值是RGB三种色组合起来的值,在读取时需要分解!

示例:

HDC hdc = GetDC(NULL);
	COLORREF Windows_Hdc_RGB = GetPixel(hdc, Mouse_X_Y.x, Mouse_X_Y.y);	//获取指定DC上的像素点RGB值
	//获取RGB,其可以使用:GetRValue,GetGvalue,GetBvalue函数代替
	WORD r = (Windows_Hdc_RGB & 0x00FF0000) >> 16;
	WORD g = (Windows_Hdc_RGB & 0x0000FF00) >> 8;
	WORD b =  Windows_Hdc_RGB & 0x000000FF;
printf("鼠标位置的颜色RGB值是:%d,%d,%d", r, g, b);

运行结果:

 

完整代码:

POINT Mouse_X_Y;	//存放鼠标坐标结构体
	if (FALSE == GetCursorPos(&Mouse_X_Y)){	//获取鼠标坐标
		printf("error:无法获取鼠标指针位于屏幕的坐标值");
	}
	printf("鼠标的X坐标:%d,鼠标的Y坐标:%d\n", Mouse_X_Y.x, Mouse_X_Y.y);
	HDC hdc = GetDC(NULL);
	COLORREF Windows_Hdc_RGB = GetPixel(hdc, Mouse_X_Y.x, Mouse_X_Y.y);	//获取指定DC上的像素点RGB值
	//获取RGB,其可以使用:GetRValue,GetGvalue,GetBvalue函数代替
	WORD r = (Windows_Hdc_RGB & 0x00FF0000) >> 16;
	WORD g = (Windows_Hdc_RGB & 0x0000FF00) >> 8;
	WORD b =  Windows_Hdc_RGB & 0x000000FF;
	printf("鼠标位置的颜色RGB值是:%d,%d,%d", r, g, b);
	getchar();

这里来说一下这三行RGB值分解代码

WORD r = (Windows_Hdc_RGB & 0x00FF0000) >> 16;
	WORD g = (Windows_Hdc_RGB & 0x0000FF00) >> 8;
	WORD b =  Windows_Hdc_RGB & 0x000000FF;

GetPixel函数返回的是DC下像素点RGB值,也就是(255,255,255)组合的十六进制值就是:0xFFFFFF(十进制的255对应0xFF十六进制),1个字节最大范围能表示255,所以我们要分别取RGB每个值就将返回的值拆分成3个字节来处理!

比如指定像素点下RGB值是137,47,66,那么137会放在高位,47会放在中位,66会放在低位用四个字节来存储它们,但是如果你直接打印的话,就是4个字节表示的值,并非1374766,

比如一个四字节的存储空间,BIT位就是:00000000 00000000 0000000 00000000

那么第三个字节用于存储R,倒数第二个字节用于存储G,最后一个用于存储B

但是如果你直接打印的话并非每个字节表示的数加在一起的,而是所有字节的BIT位按次方运算出来的结果!

计算机内部本身是没有加减乘除的,只有通过位移BIT位和次方运算得出结果!

那么如果我们要取R的值,需要先进行与运算

COLORREF原型是WORD,而WORD占4字节,0XFF表示一个字节(bit:11111111),所以我们先用与运算将Windows_Hdc_RGB里的BIT位于0x00FF0000进行运算:0x00FF0000=00000000 11111111 00000000 00000000

与运算是将两个数bit位上相同的值保留,所以这里我们只保留了第三个字节上的位数,其余的全部置0!

比如Windows_Hdc_RGB上的值是:00000000 01010000 10010100 00000001

那么经过与运算之后就为:

00000000 01010000 00000000 00000000

这里还不能直接用赋值的方式接受它的值,因为直接进行与运算的话仅仅是改变的BIT位,但是返回只会返回最低位一组bit位,所以我们要将bit位右移16位放到低位!

00000000 01010000 0000000 00000000 >> 16

00000000 00000000 0000000 01010000,然后在用赋值运算符获得位!

WORD r = (Windows_Hdc_RGB & 0x00FF0000) >> 16;

以此类推,下面两个就较为容易理解了,加上括号只是考虑到优先级的问题!

WORD g = (Windows_Hdc_RGB & 0x0000FF00) >> 8;
	WORD b =  Windows_Hdc_RGB & 0x000000FF;

其实也可以使用更加简单的方法,就是调用Windows宏函数:GetRValue、GetGValue、GetBValue

示例:
WORD r = GetRValue(Windows_Hdc_RGB);
	WORD g = GetGValue(Windows_Hdc_RGB);
WORD b = GetBValue(Windows_Hdc_RGB);

我们按下F12看声明与定义可以看到其内部实现和我们上面用的方法一致:

 

LOBYTE宏函数:

 

不过可以看到它是以BGR顺序来读取的,但是GetPixel是以RGB顺序保存的,所以建议使用上面的方法,不然可能会导致获取到的颜色表示顺序错乱掉,但是也可以把宏函数的调用顺序改一下就可以了!

这里在说说一般像素点的存储都是:

00000000 00000000 00000000 00000000 = AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB

A=透明度

R=红色

G=黄色

V=蓝色

RGB556格式:RRRRR000 GGGGG000 BBBBBB00

RGB555格式:RRRRR000 GGGGG000 BBBBB000

不过我们在内存中读取的时候也要考虑一下大小端的问题!

相关资料:图像理论知识

 

  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

17岁boy想当攻城狮

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值