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 // 任意的打印機數據
);
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;
}
{
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();
}
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;
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);
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;
}
}
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;
}
}
}
}
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;
}
}
}
}