基于C#制作一個(gè)顏色拾取器
1.目的
獲取屏幕上任意位置像素的色值。
2.知識(shí)點(diǎn)
熱鍵的注冊(cè)與注銷(xiāo)。
/// <summary>
/// 熱鍵注冊(cè)
/// </summary>
/// <param name="hWnd">要定義熱鍵的窗口的句柄 </param>
/// <param name="id">定義熱鍵ID(不能與其它ID重復(fù)) </param>
/// <param name="fsModifiers">標(biāo)識(shí)熱鍵是否在按Alt、Ctrl、Shift、Windows等鍵時(shí)才會(huì)生效 </param>
/// <param name="vk">定義熱鍵的內(nèi)容 </param>
/// <returns>如果函數(shù)執(zhí)行成功,返回值不為0。如果函數(shù)執(zhí)行失敗,返回值為0。要得到擴(kuò)展錯(cuò)誤信息,調(diào)用GetLastError。</returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);
/// <summary>
/// 熱鍵注銷(xiāo)
/// </summary>
/// <param name="hWnd">要取消熱鍵的窗口的句柄 </param>
/// <param name="id">要取消熱鍵的ID </param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
顏色的獲取。
/// <summary>
/// 在一個(gè)指定設(shè)備場(chǎng)景中獲取一個(gè)像素的RGB值
/// </summary>
/// <param name="hDC">設(shè)備場(chǎng)景的句柄</param>
/// <param name="XPos">邏輯坐標(biāo)中要檢查點(diǎn)的X坐標(biāo)</param>
/// <param name="YPos">邏輯坐標(biāo)中要檢查點(diǎn)的Y坐標(biāo)</param>
/// <returns>返回一個(gè)32位包含ARGB的UInt</returns>
[DllImport("gdi32.dll")]
static public extern uint GetPixel(IntPtr hDC, int XPos, int YPos);
獲取的顏色值(32位Uint 數(shù)據(jù)類(lèi)型),A ,R,G,B分布如下:

與常規(guī)A,R,G,B排序有所區(qū)別,而且獲取的Alpha部分始終為0。
3.效果展示


4.代碼
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Timer t = new Timer() { Interval = 100 };
IntPtr displayHwd;
private void Form1_Load(object sender, EventArgs e)
{
APIHelper.RegisterHotKey(this.Handle, 81, KeyModifiers.Shift, Keys.C);
this.TopMost = checkBox1.Checked;
t.Tick += T_Tick;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
APIHelper.UnregisterHotKey(this.Handle, 81);
}
/// <summary>
/// 獲取color從左至右第4個(gè)byte作為Blue值
/// </summary>
/// <param name="color"></param>
/// <returns></returns>
byte GetBlue(uint color)
{
return (byte)(color>>16);
}
byte GetGreen(uint color)
{
//向右移動(dòng)8位
return (byte)(color >> 8);
}
byte GetRed(uint color)
{
return (byte)(color);
}
byte GetAlpha(uint color)
{
return (byte)(color >> 24);
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
this.TopMost = checkBox1.Checked;
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnStart_Click(object sender, EventArgs e)
{
if (btnStart.Text == "開(kāi)始")
{
t.Start();
btnStart.BackColor = Color.LightGreen;
btnStart.Text = "停止";
displayHwd= APIHelper.CreateDC("DISPLAY", null, null, IntPtr.Zero);
}
else
{
btnStart.Text = "開(kāi)始";
t.Stop();
btnStart.BackColor = SystemColors.Control;
APIHelper.DeleteDC(displayHwd);
}
}
protected override void WndProc(ref Message m)
{
//WM_HOTKEY=0x0312,熱鍵關(guān)聯(lián)的消息ID
const int WM_HOTKEY = 0x0312;
//按快捷鍵
switch (m.Msg)
{
case WM_HOTKEY:
switch (m.WParam.ToInt32())
{
case 81: //按下的是Shift+C
Clipboard.SetText(txtColor.Text);
break;
}
break;
}
base.WndProc(ref m);
}
List<string> list = new List<string>();
private void T_Tick(object sender, EventArgs e)
{
Point mousePoint= Control.MousePosition;
txtPoint.Text = $"X:{mousePoint.X},Y:{mousePoint.Y}";
if(Control.MouseButtons== MouseButtons.Left)
{
uint colorVal = APIHelper.GetPixel(displayHwd, mousePoint.X, mousePoint.Y);
list.Clear();
byte[] bytes = BitConverter.GetBytes(colorVal);
BitArray array = new BitArray(bytes);
foreach (bool bit in array)
{
if (bit)
{
list.Add("1");
}
else
{
list.Add("0");
}
}
list.Reverse();
txtMonitor.Text = string.Join(" ", list);
byte red = GetRed(colorVal);
byte green = GetGreen(colorVal);
byte blue = GetBlue(colorVal);
byte alpha = GetAlpha(colorVal);
panel1.BackColor = Color.FromArgb( red, green, blue);
txtColor.Text = ColorTranslator.ToHtml(panel1.BackColor).ToString();
txtRGB.Text = $"{red},{green},{blue}";
btnStart.Text = "開(kāi)始";
t.Stop();
btnStart.BackColor = SystemColors.Control;
APIHelper.DeleteDC(displayHwd);
}
}
}
[Flags()]
public enum KeyModifiers
{
None = 0,
Alt = 1,
Ctrl = 2,
Shift = 4,
WindowsKey = 8
}
class APIHelper
{
/// <summary>
/// 在一個(gè)指定設(shè)備場(chǎng)景中獲取一個(gè)像素的RGB值
/// </summary>
/// <param name="hDC">設(shè)備場(chǎng)景的句柄</param>
/// <param name="XPos">邏輯坐標(biāo)中要檢查點(diǎn)的X坐標(biāo)</param>
/// <param name="YPos">邏輯坐標(biāo)中要檢查點(diǎn)的Y坐標(biāo)</param>
/// <returns>返回一個(gè)32位包含ARGB的UInt</returns>
[DllImport("gdi32.dll")]
static public extern uint GetPixel(IntPtr hDC, int XPos, int YPos);
/// <summary>
/// 為專(zhuān)門(mén)設(shè)備創(chuàng)建設(shè)備場(chǎng)景
/// </summary>
/// <param name="driverName">如果此參數(shù)為DISPLAY則代表整個(gè)屏幕的設(shè)備場(chǎng)景,如果為WINSPOOL則訪(fǎng)問(wèn)打印機(jī)驅(qū)動(dòng)</param>
/// <param name="deviceName">所用專(zhuān)門(mén)設(shè)備的名稱(chēng)</param>
/// <param name="output">用null給該參數(shù)</param>
/// <param name="lpinitData">DEVMODE,該結(jié)構(gòu)保存初始值</param>
/// <returns>設(shè)備場(chǎng)景的句柄</returns>
[DllImport("gdi32.dll")]
static public extern IntPtr CreateDC(string driverName, string deviceName, string output, IntPtr lpinitData);
/// <summary>
/// 在一個(gè)指定設(shè)備場(chǎng)景中獲取一個(gè)像素的RGB值
/// </summary>
/// <param name="DC">設(shè)備場(chǎng)景的句柄</param>
/// <returns></returns>
[DllImport("gdi32.dll")]
static public extern bool DeleteDC(IntPtr DC);
/// <summary>
/// 熱鍵注冊(cè)
/// </summary>
/// <param name="hWnd">要定義熱鍵的窗口的句柄 </param>
/// <param name="id">定義熱鍵ID(不能與其它ID重復(fù)) </param>
/// <param name="fsModifiers">標(biāo)識(shí)熱鍵是否在按Alt、Ctrl、Shift、Windows等鍵時(shí)才會(huì)生效 </param>
/// <param name="vk">定義熱鍵的內(nèi)容 </param>
/// <returns>如果函數(shù)執(zhí)行成功,返回值不為0。如果函數(shù)執(zhí)行失敗,返回值為0。要得到擴(kuò)展錯(cuò)誤信息,調(diào)用GetLastError。</returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);
/// <summary>
/// 熱鍵注銷(xiāo)
/// </summary>
/// <param name="hWnd">要取消熱鍵的窗口的句柄 </param>
/// <param name="id">要取消熱鍵的ID </param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
}到此這篇關(guān)于基于C#制作一個(gè)顏色拾取器的文章就介紹到這了,更多相關(guān)C#顏色拾取器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
unity實(shí)現(xiàn)貼圖矩陣運(yùn)算(旋轉(zhuǎn)平移縮放)
這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)貼圖矩陣運(yùn)算,旋轉(zhuǎn)平移縮放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
使用C#開(kāi)發(fā)OPC?Server服務(wù)器源碼解析
OPC?Server服務(wù)器服務(wù)器的開(kāi)發(fā)比較繁瑣,本示例采用C#提供了一種簡(jiǎn)單快速實(shí)現(xiàn)OPCServer的方法,已經(jīng)在工程項(xiàng)目中應(yīng)用,本文對(duì)C#開(kāi)發(fā)OPC?Server服務(wù)器相關(guān)知識(shí)給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-06-06
C#創(chuàng)建安全的棧(Stack)存儲(chǔ)結(jié)構(gòu)
這篇文章主要為大家詳細(xì)介紹了C#創(chuàng)建安全的棧(Stack)存儲(chǔ)結(jié)構(gòu)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
IIS下調(diào)用證書(shū)出現(xiàn)異常的解決方法 (C#)
這篇文章主要為大家詳細(xì)介紹了IIS下調(diào)用證書(shū)出現(xiàn)異常的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
Netcore?Webapi返回?cái)?shù)據(jù)的三種方式示例
這篇文章主要為大家介紹了Netcore?Webapi返回?cái)?shù)據(jù)的三種方式示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
C#使用CefSharp控件實(shí)現(xiàn)爬蟲(chóng)
這篇文章介紹了C#使用CefSharp控件實(shí)現(xiàn)爬蟲(chóng)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
TextBox獲取輸入焦點(diǎn)時(shí)自動(dòng)全選的實(shí)現(xiàn)方法
TextBox獲取輸入焦點(diǎn)時(shí)自動(dòng)全選的實(shí)現(xiàn)方法,需要的朋友可以參考一下2013-03-03

