C#抓屏
要想完成這個功能,首先要了解一下在C#中如何調(diào)用API(應(yīng)用程序接口)函數(shù)。雖然在.Net框架中已經(jīng)提供了許多類庫,這些類庫的功能也十分強大,但對于一些Windows底層編程來說,還是要通過調(diào)用這些API函數(shù)才可以實現(xiàn)。所有API都在"Kernel"、"User "和"GDI"三個庫中得以運行:其中"Kernel",他的庫名為 "KERNEL32.DLL", 他主要用于產(chǎn)生與操作系統(tǒng)之間的關(guān)聯(lián),譬如:程序加載,上下文選擇,文件輸入輸出,內(nèi)存管理等等。"User "這個類庫在Win32中名叫 "USER32.DLL"。 它允許管理全部的用戶接口。譬如:窗口 、菜單 、對話框 、圖標(biāo)等等。"GDI"(圖象設(shè)備接口),它在Win32中的庫名為:"GDI32.dll",它是圖形輸出庫。使用GDI Windows"畫"出窗口、菜單以及對話框等;它能創(chuàng)建圖形輸出;它也能保存圖形文件。由于本文所涉及到是圖象問題,所有調(diào)用的類庫是"GDI32.dll"。在本文程序中我們使用的API函數(shù)是"BitBlt",這個函數(shù)對于廣大程序員來說,一定不感覺到陌生,因為在圖象處理方面他的用途是相對廣的,在用其他程序語言編程中,時常也要和他打交道。在.Net FrameWork SDK中有一個名字空間"System.Runtime.InteropServices",此名字空間提供了一系列的類來訪問COM對象,和調(diào)用本地的API函數(shù)。下面是在C#中聲明此函數(shù):
[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
private static extern bool BitBlt (
?????IntPtr hdcDest , // 目標(biāo) DC的句柄
?????int nXDest ,
???int nYDest ,
???int nWidth ,
???int nHeight ,
???IntPtr hdcSrc ,??// 源DC的句柄
?????int nXSrc ,
???int nYSrc ,
???System.Int32 dwRop??// 光柵的處理數(shù)值
?????) ;
??
通過上面這個聲明,就可以在下面的代碼中使用此函數(shù)了。
下面是用C#做屏幕捕獲程序的具體實現(xiàn)步驟:
(1).首先要獲得當(dāng)前屏幕的graphic對象,通過以下代碼可以實現(xiàn):
Graphics g1 = this.CreateGraphics ( ) ;??
(2).創(chuàng)建一個Bitmap對象,并且這個Bitmap對象的大小是當(dāng)前屏幕:
首先要獲得當(dāng)前屏幕的大小,通過名字空間"System.Windows.Forms"中的"Screen"類的GetWorkingArea()方法,可以實現(xiàn)。下面是得到當(dāng)前屏幕的長(Height)和寬(Width):
Rectangle rect = new Rectangle ( ) ;
rect = Screen.GetWorkingArea ( this ) ;
"屏幕寬"= rect.Width ;
"屏幕長"= rect.Height ;
至此就可以得到我們想要的Bitmap了,通過下列語句可以實現(xiàn):
Image MyImage = new Bitmap ( rect.Width , rect.Height , g1 ) ;
//創(chuàng)建以屏幕大小為標(biāo)準(zhǔn)的位圖??
(3).獲得當(dāng)前屏幕和此Bitmap對象的DC,這可以通過下列語句實現(xiàn):
//得到屏幕的DC
IntPtr dc1 = g1.GetHdc ( ) ;
//得到Bitmap的DC
IntPtr dc2 = g2.GetHdc ( ) ;
(4).調(diào)用API函數(shù),把當(dāng)前屏幕拷貝到創(chuàng)建的Bitmap中:
BitBlt ( dc2 , 0 , 0 , rect.Width , rect.Height , dc1 , 0 , 0 , 13369376 ) ;??
(5).釋放當(dāng)前屏幕和此Bitmap對象的DC,通過下面代碼可以實現(xiàn):
//釋放掉屏幕的DC
g1.ReleaseHdc ( dc1 ) ;
//釋放掉Bitmap的DC
g2.ReleaseHdc ( dc2 ) ;
(6).保存Bitmap對象,形成jpg圖片:
MyImage.Save ( @"c:/Capture.jpg" , ImageFormat.Jpeg );??
當(dāng)然你也可以根據(jù)自己的需要,把屏幕以其他圖片的格式來保存,如果你想把圖片保存為位圖文件,可以把"ImageFormat.Jpeg"改換成"ImageFormat.Bmp";想把圖片保存為Gif文件,就把"ImageFormat.Jpeg"改換成"ImageFormat.Gif"。你可以保存的文件類型大概有十多種,這里就不一一介紹了,當(dāng)然你也要相應(yīng)改變保存文件的后綴。?
用C#來捕獲屏幕的源程序代碼(Capture.cs):
了解上面的這些步驟的實現(xiàn)方法,就可以得到用C#捕獲屏幕的源程序,如下:
using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.Drawing.Imaging ;
public class Form1 : Form
{
private Button button1 ;
private System.ComponentModel.Container components = null ;
public Form1 ( )
{
//初始化窗體中的各個組件
InitializeComponent ( ) ;
}
// 清除程序中使用過的資源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null )
{
components.Dispose ( ) ;
}
}
base.Dispose ( disposing ) ;
}
private void InitializeComponent ( )
{
button1 = new Button ( );
SuspendLayout ( ) ;
button1.Location = new System.Drawing.Point ( 64 , 40 ) ;
button1.Name = "button1" ;
button1.Size = new System.Drawing.Size ( 80 , 32 ) ;
button1.TabIndex = 0 ;
button1.Text = "捕獲" ;
button1.Click += new System.EventHandler ( button1_Click ) ;
AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ;
ClientSize = new System.Drawing.Size ( 216 , 125 ) ;
Controls.Add??( button1 ) ;
MaximizeBox = false ;
MinimizeBox = false ;
Name = "Form1" ;
Text = "C#捕獲當(dāng)前屏幕!" ;
ResumeLayout ( false ) ;
}
//聲明一個API函數(shù)
[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
private static extern bool BitBlt (
?????IntPtr hdcDest , // 目標(biāo) DC的句柄
?????int nXDest ,
???int nYDest ,
int nWidth ,
???int nHeight ,
???IntPtr hdcSrc ,??// 源DC的句柄
?????int nXSrc ,
???int nYSrc ,
???System.Int32 dwRop??// 光柵的處理數(shù)值
?????) ;
static void Main ( )
{
Application.Run ( new Form1 ( ) ) ;
}
private void button1_Click ( object sender , System.EventArgs e )
{
?????//獲得當(dāng)前屏幕的大小
???????????Rectangle rect = new Rectangle ( ) ;
?????rect = Screen.GetWorkingArea ( this ) ;
?????//創(chuàng)建一個以當(dāng)前屏幕為模板的圖象
?????Graphics g1 = this.CreateGraphics ( ) ;
?????//創(chuàng)建以屏幕大小為標(biāo)準(zhǔn)的位圖
???Image MyImage = new Bitmap ( rect.Width , rect.Height , g1 ) ;
?????Graphics g2 = Graphics.FromImage ( MyImage ) ;
?????//得到屏幕的DC
?????IntPtr dc1 = g1.GetHdc ( ) ;
?????//得到Bitmap的DC
???IntPtr dc2 = g2.GetHdc ( ) ;
?????//調(diào)用此API函數(shù),實現(xiàn)屏幕捕獲
?????BitBlt ( dc2 , 0 , 0 , rect.Width , rect.Height , dc1 , 0 , 0 , 13369376 ) ;
?????//釋放掉屏幕的DC
?????g1.ReleaseHdc ( dc1 ) ;
?????//釋放掉Bitmap的DC
???g2.ReleaseHdc ( dc2 ) ;
?????//以JPG文件格式來保存
?????MyImage.Save ( @"c:/Capture.jpg" , ImageFormat.Jpeg );
?????MessageBox.Show ( "當(dāng)前屏幕已經(jīng)保存為C盤的capture.jpg文件!" ) ;
}
}??
?
[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
private static extern bool BitBlt (
?????IntPtr hdcDest , // 目標(biāo) DC的句柄
?????int nXDest ,
???int nYDest ,
???int nWidth ,
???int nHeight ,
???IntPtr hdcSrc ,??// 源DC的句柄
?????int nXSrc ,
???int nYSrc ,
???System.Int32 dwRop??// 光柵的處理數(shù)值
?????) ;
??
通過上面這個聲明,就可以在下面的代碼中使用此函數(shù)了。
下面是用C#做屏幕捕獲程序的具體實現(xiàn)步驟:
(1).首先要獲得當(dāng)前屏幕的graphic對象,通過以下代碼可以實現(xiàn):
Graphics g1 = this.CreateGraphics ( ) ;??
(2).創(chuàng)建一個Bitmap對象,并且這個Bitmap對象的大小是當(dāng)前屏幕:
首先要獲得當(dāng)前屏幕的大小,通過名字空間"System.Windows.Forms"中的"Screen"類的GetWorkingArea()方法,可以實現(xiàn)。下面是得到當(dāng)前屏幕的長(Height)和寬(Width):
Rectangle rect = new Rectangle ( ) ;
rect = Screen.GetWorkingArea ( this ) ;
"屏幕寬"= rect.Width ;
"屏幕長"= rect.Height ;
至此就可以得到我們想要的Bitmap了,通過下列語句可以實現(xiàn):
Image MyImage = new Bitmap ( rect.Width , rect.Height , g1 ) ;
//創(chuàng)建以屏幕大小為標(biāo)準(zhǔn)的位圖??
(3).獲得當(dāng)前屏幕和此Bitmap對象的DC,這可以通過下列語句實現(xiàn):
//得到屏幕的DC
IntPtr dc1 = g1.GetHdc ( ) ;
//得到Bitmap的DC
IntPtr dc2 = g2.GetHdc ( ) ;
(4).調(diào)用API函數(shù),把當(dāng)前屏幕拷貝到創(chuàng)建的Bitmap中:
BitBlt ( dc2 , 0 , 0 , rect.Width , rect.Height , dc1 , 0 , 0 , 13369376 ) ;??
(5).釋放當(dāng)前屏幕和此Bitmap對象的DC,通過下面代碼可以實現(xiàn):
//釋放掉屏幕的DC
g1.ReleaseHdc ( dc1 ) ;
//釋放掉Bitmap的DC
g2.ReleaseHdc ( dc2 ) ;
(6).保存Bitmap對象,形成jpg圖片:
MyImage.Save ( @"c:/Capture.jpg" , ImageFormat.Jpeg );??
當(dāng)然你也可以根據(jù)自己的需要,把屏幕以其他圖片的格式來保存,如果你想把圖片保存為位圖文件,可以把"ImageFormat.Jpeg"改換成"ImageFormat.Bmp";想把圖片保存為Gif文件,就把"ImageFormat.Jpeg"改換成"ImageFormat.Gif"。你可以保存的文件類型大概有十多種,這里就不一一介紹了,當(dāng)然你也要相應(yīng)改變保存文件的后綴。?
用C#來捕獲屏幕的源程序代碼(Capture.cs):
了解上面的這些步驟的實現(xiàn)方法,就可以得到用C#捕獲屏幕的源程序,如下:
using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.Drawing.Imaging ;
public class Form1 : Form
{
private Button button1 ;
private System.ComponentModel.Container components = null ;
public Form1 ( )
{
//初始化窗體中的各個組件
InitializeComponent ( ) ;
}
// 清除程序中使用過的資源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null )
{
components.Dispose ( ) ;
}
}
base.Dispose ( disposing ) ;
}
private void InitializeComponent ( )
{
button1 = new Button ( );
SuspendLayout ( ) ;
button1.Location = new System.Drawing.Point ( 64 , 40 ) ;
button1.Name = "button1" ;
button1.Size = new System.Drawing.Size ( 80 , 32 ) ;
button1.TabIndex = 0 ;
button1.Text = "捕獲" ;
button1.Click += new System.EventHandler ( button1_Click ) ;
AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ;
ClientSize = new System.Drawing.Size ( 216 , 125 ) ;
Controls.Add??( button1 ) ;
MaximizeBox = false ;
MinimizeBox = false ;
Name = "Form1" ;
Text = "C#捕獲當(dāng)前屏幕!" ;
ResumeLayout ( false ) ;
}
//聲明一個API函數(shù)
[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
private static extern bool BitBlt (
?????IntPtr hdcDest , // 目標(biāo) DC的句柄
?????int nXDest ,
???int nYDest ,
int nWidth ,
???int nHeight ,
???IntPtr hdcSrc ,??// 源DC的句柄
?????int nXSrc ,
???int nYSrc ,
???System.Int32 dwRop??// 光柵的處理數(shù)值
?????) ;
static void Main ( )
{
Application.Run ( new Form1 ( ) ) ;
}
private void button1_Click ( object sender , System.EventArgs e )
{
?????//獲得當(dāng)前屏幕的大小
???????????Rectangle rect = new Rectangle ( ) ;
?????rect = Screen.GetWorkingArea ( this ) ;
?????//創(chuàng)建一個以當(dāng)前屏幕為模板的圖象
?????Graphics g1 = this.CreateGraphics ( ) ;
?????//創(chuàng)建以屏幕大小為標(biāo)準(zhǔn)的位圖
???Image MyImage = new Bitmap ( rect.Width , rect.Height , g1 ) ;
?????Graphics g2 = Graphics.FromImage ( MyImage ) ;
?????//得到屏幕的DC
?????IntPtr dc1 = g1.GetHdc ( ) ;
?????//得到Bitmap的DC
???IntPtr dc2 = g2.GetHdc ( ) ;
?????//調(diào)用此API函數(shù),實現(xiàn)屏幕捕獲
?????BitBlt ( dc2 , 0 , 0 , rect.Width , rect.Height , dc1 , 0 , 0 , 13369376 ) ;
?????//釋放掉屏幕的DC
?????g1.ReleaseHdc ( dc1 ) ;
?????//釋放掉Bitmap的DC
???g2.ReleaseHdc ( dc2 ) ;
?????//以JPG文件格式來保存
?????MyImage.Save ( @"c:/Capture.jpg" , ImageFormat.Jpeg );
?????MessageBox.Show ( "當(dāng)前屏幕已經(jīng)保存為C盤的capture.jpg文件!" ) ;
}
}??
?
總結(jié)