C#取屏幕顏色
1.原理
調用API取得屏幕上一個象素大小的位圖,這個位圖的底色就是鼠標所在點的屏幕顏色.
2.實現
--1.先聲明API
[DllImport(
"
gdi32.dll
"
)]
private
static
extern
bool
BitBlt(
IntPtr hdcDest,
//
目標設備的句柄
int
nXDest,
//
目標對像的左上角的X坐標
int
nYDest,
//
目標對像的左上角的X坐標
int
nWidth,
//
目標對像的矩形的寬度
int
nHeight,
//
目標對像的矩形的長度
IntPtr hdcSrc,
//
源設備的句柄
int
nXSrc,
//
源對像的左上角的X坐標
int
nYSrc,
//
源對像的左上角的X坐標
int
dwRop
//
光柵的操作值
);
[DllImport(
"
gdi32.dll
"
)]
private
static
extern
IntPtr CreateDC(
string
lpszDriver,
//
驅動名稱
string
lpszDevice,
//
設備名稱
string
lpszOutput,
//
無用,可以設定位"NULL"
IntPtr lpInitData
//
任意的打印機數據
);
--2.編寫取色函數
private
Color GetArgb()
{
Color rtnColor;
//
創建顯示器的DC
IntPtr hdlDisplay
=
CreateDC(
"
DISPLAY
"
,
null
,
null
, IntPtr.Zero);
//
從指定設備的句柄創建新的 Graphics 對像
Graphics gfxDisplay
=
Graphics.FromHdc(hdlDisplay);
//
創建隻有一個像素大小的 Bitmap 對像
Bitmap bmp
=
new
Bitmap(
1
,
1
, gfxDisplay);
//
從指定 Image 對像創建新的 Graphics 對像
Graphics gfxBmp
=
Graphics.FromImage(bmp);
//
獲得屏幕的句柄
IntPtr hdlScreen
=
gfxDisplay.GetHdc();
//
獲得位圖的句柄
IntPtr hdlBmp
=
gfxBmp.GetHdc();
//
把當前屏幕中鼠標指針所在位置的一個像素拷貝到位圖中
BitBlt(hdlBmp,
0
,
0
,
1
,
1
, hdlScreen, MousePosition.X, MousePosition.Y,
13369376
);
//
釋放屏幕句柄
gfxDisplay.ReleaseHdc(hdlScreen);
//
釋放位圖句柄
gfxBmp.ReleaseHdc(hdlBmp);
rtnColor
=
bmp.GetPixel(
0
,
0
);
//
獲取像素的顏色
bmp.Dispose();
//
釋放 bmp 所使用的資源
return
rtnColor;
}
3.触發事件
這里采用時間触發方式.
Bug:我認為采用鼠標移動時触發更合适.
this
.tmr.Tick
+=
new
System.EventHandler(
this
.tmr_Tick);
private
void
tmr_Tick(
object
sender, EventArgs e)
{
lblColor.BackColor
=
GetArgb();
txtArgb.Text
=
lblColor.BackColor.R.ToString()
+
"
,
"
+
lblColor.BackColor.G.ToString()
+
"
,
"
+
lblColor.BackColor.B.ToString();
}
4.調整顯示窗体
當鼠標移到當前窗体時,窗体需要移開.
先聲明變量:
//
桌面工作區的尺寸
Size workingArea;
//
Form 的初始位置和在左下角,右下角的位置
Point formLoc, ptLeftBottom, ptRightBottom;
初始化變量:
Rectangle rect
=
SystemInformation.WorkingArea;
workingArea
=
new
Size(rect.Width, rect.Height);
ptLeftBottom
=
new
Point(
0
, workingArea.Height
-
this
.Height);
ptRightBottom
=
new
Point(workingArea.Width
-
this
.Width, workingArea.Height
-
this
.Height);
触發事件:
this
.MouseEnter
+=
new
System.EventHandler(
this
.Form1_MouseEnter);
private
void
Form1_MouseEnter(
object
sender, EventArgs e)
{
if
(
this
.Location
==
ptLeftBottom)
//
窗體在左下角
{
this
.Location
=
ptRightBottom;
}
else
if
(
this
.Location
==
ptRightBottom)
//
窗體在右下角
{
this
.Location
=
ptLeftBottom;
}
}
3.全部源碼,可運行
using
System;
using
System.Drawing;
using
System.Collections;
using
System.ComponentModel;
using
System.Windows.Forms;
using
System.Data;
using
System.Drawing.Imaging;
using
System.Runtime.InteropServices;
namespace
PrintDemo
{
///
<summary>
///
Form1 的摘要說明。
///
</summary>
public
class
Form1 : System.Windows.Forms.Form
{
//
桌面工作區的尺寸
Size workingArea;
//
Form 的初始位置和在左下角,右下角的位置
Point formLoc, ptLeftBottom, ptRightBottom;
private
System.Windows.Forms.Label lblColor;
private
System.Windows.Forms.TextBox txtArgb;
private
System.Windows.Forms.Timer tmr;
private
System.Windows.Forms.ToolTip tip;
private
System.ComponentModel.IContainer components;
public
Form1()
{
InitializeComponent();
this
.FormBorderStyle
=
FormBorderStyle.FixedToolWindow;
this
.StartPosition
=
FormStartPosition.CenterScreen;
Rectangle rect
=
SystemInformation.WorkingArea;
workingArea
=
new
Size(rect.Width, rect.Height);
ptLeftBottom
=
new
Point(
0
, workingArea.Height
-
this
.Height);
ptRightBottom
=
new
Point(workingArea.Width
-
this
.Width,
workingArea.Height
-
this
.Height);
String tipMsg
=
"
在窗體空白處雙擊鼠標左鍵開始取色,按ESC鍵確定顏色
"
;
tip.SetToolTip(
this
, tipMsg);
tip.SetToolTip(lblColor, tipMsg);
tip.SetToolTip(txtArgb, tipMsg);
}
///
<summary>
///
清理所有正在使用的資源。
///
</summary>
protected
override
void
Dispose(
bool
disposing)
{
if
(disposing)
{
if
(components
!=
null
)
{
components.Dispose();
}
}
base
.Dispose(disposing);
}
#region
Windows Form Designer generated code
///
<summary>
///
設計器支持所需的方法 - 不要使用代碼編輯器修改
///
此方法的內容。
///
</summary>
private
void
InitializeComponent()
{
this
.components
=
new
System.ComponentModel.Container();
this
.lblColor
=
new
System.Windows.Forms.Label();
this
.tmr
=
new
System.Windows.Forms.Timer(
this
.components);
this
.txtArgb
=
new
System.Windows.Forms.TextBox();
this
.tip
=
new
System.Windows.Forms.ToolTip(
this
.components);
this
.SuspendLayout();
//
//
lblColor
//
this
.lblColor.BorderStyle
=
System.Windows.Forms.BorderStyle.FixedSingle;
this
.lblColor.Location
=
new
System.Drawing.Point(
8
,
8
);
this
.lblColor.Name
=
"
lblColor
"
;
this
.lblColor.Size
=
new
System.Drawing.Size(
120
,
23
);
this
.lblColor.TabIndex
=
0
;
//
//
tmr
//
this
.tmr.Tick
+=
new
System.EventHandler(
this
.tmr_Tick);
//
//
txtArgb
//
this
.txtArgb.BorderStyle
=
System.Windows.Forms.BorderStyle.FixedSingle;
this
.txtArgb.Font
=
new
System.Drawing.Font(
"
Arial
"
,
10.5F
, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(
0
)));
this
.txtArgb.Location
=
new
System.Drawing.Point(
8
,
40
);
this
.txtArgb.Name
=
"
txtArgb
"
;
this
.txtArgb.Size
=
new
System.Drawing.Size(
120
,
24
);
this
.txtArgb.TabIndex
=
1
;
this
.txtArgb.Text
=
""
;
this
.txtArgb.KeyPress
+=
new
System.Windows.Forms.KeyPressEventHandler(
this
.txtArgb_KeyPress);
//
//
Form1
//
this
.AutoScaleBaseSize
=
new
System.Drawing.Size(
6
,
14
);
this
.ClientSize
=
new
System.Drawing.Size(
136
,
69
);
this
.Controls.Add(
this
.txtArgb);
this
.Controls.Add(
this
.lblColor);
this
.Name
=
"
Form1
"
;
this
.Text
=
"
屏幕取色(upto)
"
;
this
.DoubleClick
+=
new
System.EventHandler(
this
.Form1_DoubleClick);
this
.MouseEnter
+=
new
System.EventHandler(
this
.Form1_MouseEnter);
this
.ResumeLayout(
false
);
}
#endregion
[DllImport(
"
gdi32.dll
"
)]
private
static
extern
bool
BitBlt(
IntPtr hdcDest,
//
目標設備的句柄
int
nXDest,
//
目標對像的左上角的X坐標
int
nYDest,
//
目標對像的左上角的X坐標
int
nWidth,
//
目標對像的矩形的寬度
int
nHeight,
//
目標對像的矩形的長度
IntPtr hdcSrc,
//
源設備的句柄
int
nXSrc,
//
源對像的左上角的X坐標
int
nYSrc,
//
源對像的左上角的X坐標
int
dwRop
//
光柵的操作值
);
[DllImport(
"
gdi32.dll
"
)]
private
static
extern
IntPtr CreateDC(
string
lpszDriver,
//
驅動名稱
string
lpszDevice,
//
設備名稱
string
lpszOutput,
//
無用,可以設定位"NULL"
IntPtr lpInitData
//
任意的打印機數據
);
private
void
Form1_DoubleClick(
object
sender, EventArgs e)
{
formLoc
=
this
.Location;
this
.Location
=
ptRightBottom;
this
.TopMost
=
true
;
tmr.Enabled
=
true
;
}
private
Color GetArgb()
{
Color rtnColor;
//
創建顯示器的DC
IntPtr hdlDisplay
=
CreateDC(
"
DISPLAY
"
,
null
,
null
, IntPtr.Zero);
//
從指定設備的句柄創建新的 Graphics 對像
Graphics gfxDisplay
=
Graphics.FromHdc(hdlDisplay);
//
創建隻有一個像素大小的 Bitmap 對像
Bitmap bmp
=
new
Bitmap(
1
,
1
, gfxDisplay);
//
從指定 Image 對像創建新的 Graphics 對像
Graphics gfxBmp
=
Graphics.FromImage(bmp);
//
獲得屏幕的句柄
IntPtr hdlScreen
=
gfxDisplay.GetHdc();
//
獲得位圖的句柄
IntPtr hdlBmp
=
gfxBmp.GetHdc();
//
把當前屏幕中鼠標指針所在位置的一個像素拷貝到位圖中
BitBlt(hdlBmp,
0
,
0
,
1
,
1
, hdlScreen, MousePosition.X, MousePosition.Y,
13369376
);
//
釋放屏幕句柄
gfxDisplay.ReleaseHdc(hdlScreen);
//
釋放位圖句柄
gfxBmp.ReleaseHdc(hdlBmp);
rtnColor
=
bmp.GetPixel(
0
,
0
);
//
獲取像素的顏色
bmp.Dispose();
//
釋放 bmp 所使用的資源
return
rtnColor;
}
private
void
tmr_Tick(
object
sender, EventArgs e)
{
lblColor.BackColor
=
GetArgb();
txtArgb.Text
=
lblColor.BackColor.R.ToString()
+
"
,
"
+
lblColor.BackColor.G.ToString()
+
"
,
"
+
lblColor.BackColor.B.ToString();
}
private
void
txtArgb_KeyPress(
object
sender, KeyPressEventArgs e)
{
//
當按下ESC鍵時,確定所取的顏色ARGB值
//
Bug:隻有當窗體處於激活狀態時才有效,以後要是能點一下右鍵就可以就好了或者換成熱鍵觸發.
if
(e.KeyChar
==
(
char
)Keys.Escape)
{
tmr.Enabled
=
false
;
this
.Location
=
formLoc;
this
.TopMost
=
false
;
txtArgb.SelectAll();
}
}
private
void
Form1_MouseEnter(
object
sender, EventArgs e)
{
if
(
this
.Location
==
ptLeftBottom)
//
窗體在左下角
{
this
.Location
=
ptRightBottom;
}
else
if
(
this
.Location
==
ptRightBottom)
//
窗體在右下角
{
this
.Location
=
ptLeftBottom;
}
}
}
}