1. 程式人生 > >Windows核心北京賽車遊戲一條龍服務編程_獲取鼠標指定位置的RGB顏色值

Windows核心北京賽車遊戲一條龍服務編程_獲取鼠標指定位置的RGB顏色值

獲得 ffffff too 包含 aaaaa window RR clip 乘除

Windows核心北京賽車遊戲一條龍服務【大神源碼論壇】dsluntan.com 【布丁源碼論壇】budingbbs.com 企娥3393756370編程_獲取鼠標指定位置的RGB顏色值

大家平常會見到很多屏幕取色工具,其原理都是獲取鼠標位置的屏幕像素點顏色!

一般思路都是:獲取鼠標位置,然後取出鼠標指向的屏幕像素點顏色!

GetCursorPos函數是WindowsSDK庫下的一個API函數,用於獲取鼠標位於屏幕中偏移的坐標信息!

函數原型:

[cpp] view plain copy
  1. BOOL GetCursorPos(LPPOINT lpPoint);
  2. 參數介紹:LPPOINT lpPoint:用於接受鼠標坐標的POINT結構體指針
  3. 返回值:成功返回TRUE,失敗返回FALSE!

示例:

[cpp] view plain copy
  1. POINT Mouse_X_Y; //存放鼠標坐標結構體
  2. if (FALSE == GetCursorPos(&Mouse_X_Y)){ //獲取鼠標坐標
  3. printf("error:無法獲取鼠標指針位於屏幕的坐標值");
  4. }
  5. printf("鼠標的X坐標:%d,鼠標的Y坐標:%d", Mouse_X_Y.x, Mouse_X_Y.y);
  6. getchar();

運行結果:

技術分享圖片

已經可以成功知道鼠標的坐標了,那麽接下來就是獲取鼠標指向屏幕上的像素點信息!

首先Windows下一個窗口的繪圖信息(像素點信息)都是由DC來描述的,DC指向一個繪圖設備表,這個表裏包含了一個窗口的所有繪圖信息,比如位於屏幕上的坐標,還有坐標上的像素點信息等等!

而且我們的窗口是顯示在屏幕上的,所以我們如果想取某個窗口的顏色,可以把窗口放到屏幕上,Windows會把窗口的繪圖信息,呈現到屏幕的DC中去!

GetDC,可以用來獲取指定程序的DC繪圖設備描述符!

函數原型:

[cpp] view plain copy
  1. HDC GetDC(HWND hWnd);
  2. 參數介紹:HWND hWnd: 窗口句柄,NULL獲取屏幕的DC句柄
  3. 返回值:窗口DC,否則返回NULL

有了窗體的繪圖信息,那麽怎麽得到DC指向的繪圖表裏的繪圖信息呢?


GetPixel 此函數是用來獲取指定DC繪圖表裏的像素點

函數原型:

[cpp] view plain copy
  1. COLORREF GetPixel(HDC hdc, int nXPos, int nYPos);
  2. 參數介紹:
  3. HDC hdc:DC
  4. int nXPos:X坐標
  5. int nYPos:Y坐標
  6. 返回值:返回DC下的RGB顏色值,註意這個值是RGB三種色組合起來的值,在讀取時需要分解!

示例:

[cpp] view plain copy
  1. HDC hdc = GetDC(NULL);
  2. COLORREF Windows_Hdc_RGB = GetPixel(hdc, Mouse_X_Y.x, Mouse_X_Y.y); //獲取指定DC上的像素點RGB值
  3. //獲取RGB,其可以使用:GetRValue,GetGvalue,GetBvalue函數代替
  4. WORD r = (Windows_Hdc_RGB & 0x00FF0000) >> 16;
  5. WORD g = (Windows_Hdc_RGB & 0x0000FF00) >> 8;
  6. WORD b = Windows_Hdc_RGB & 0x000000FF;
  7. printf("鼠標位置的顏色RGB值是:%d,%d,%d", r, g, b);

運行結果:

技術分享圖片

完整代碼:

[cpp] view plain copy
  1. POINT Mouse_X_Y; //存放鼠標坐標結構體
  2. if (FALSE == GetCursorPos(&Mouse_X_Y)){ //獲取鼠標坐標
  3. printf("error:無法獲取鼠標指針位於屏幕的坐標值");
  4. }
  5. printf("鼠標的X坐標:%d,鼠標的Y坐標:%d\n", Mouse_X_Y.x, Mouse_X_Y.y);
  6. HDC hdc = GetDC(NULL);
  7. COLORREF Windows_Hdc_RGB = GetPixel(hdc, Mouse_X_Y.x, Mouse_X_Y.y); //獲取指定DC上的像素點RGB值
  8. //獲取RGB,其可以使用:GetRValue,GetGvalue,GetBvalue函數代替
  9. WORD r = (Windows_Hdc_RGB & 0x00FF0000) >> 16;
  10. WORD g = (Windows_Hdc_RGB & 0x0000FF00) >> 8;
  11. WORD b = Windows_Hdc_RGB & 0x000000FF;
  12. printf("鼠標位置的顏色RGB值是:%d,%d,%d", r, g, b);
  13. getchar();

這裏來說一下這三行RGB值分解代碼

[cpp] view plain copy
  1. WORD r = (Windows_Hdc_RGB & 0x00FF0000) >> 16;
  2. WORD g = (Windows_Hdc_RGB & 0x0000FF00) >> 8;
  3. 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,而WORD4字節,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,然後在用賦值運算符獲得位!

[cpp] view plain copy
  1. WORD r = (Windows_Hdc_RGB & 0x00FF0000) >> 16;

以此類推,下面兩個就較為容易理解了,加上括號只是考慮到優先級的問題!

[cpp] view plain copy
  1. WORD g = (Windows_Hdc_RGB & 0x0000FF00) >> 8;
  2. WORD b = Windows_Hdc_RGB & 0x000000FF;

其實也可以使用更加簡單的方法,就是調用Windows宏函數:GetRValue、GetGValue、GetBValue

[cpp] view plain copy
  1. 示例:
  2. WORD r = GetRValue(Windows_Hdc_RGB);
  3. WORD g = GetGValue(Windows_Hdc_RGB);
  4. 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

不過我們在內存中讀取的時候也要考慮一下大小端的問題!

Windows核心北京賽車遊戲一條龍服務編程_獲取鼠標指定位置的RGB顏色值