用C#來捕獲屏幕(1)
[ 作者: 王天 添加時間: 2002-3-29 14:37:15 ]
來源: 賽迪網 www.ccidnet.com
其實用C#可以完成其他程序設計語言的幾乎全部功能,當然C#自身的許多獨到的功能,是其他程序語言所無法實現的,這就是C#越來越受到廣大程序員的喜歡的原因。本文就來探討一下用C#去實現一個重要的功能,用他來編寫一個捕獲當前屏幕地程序。通過這個程序,我們將瞭解到C#是如何調用API函數,和.Net框架中的類庫內容是多麼地豐富,功能是多麼地強大。
一. 程序設計開發及運行環境:
(1).微軟視窗2000服務器版
(2)..Net FrameWork SDK Beta 2
二. 程序設計的關鍵步驟:
要想完成這個功能,首先要了解一下在C#中如何調用API(應用程序接口)函數。雖然在.Net框架中已經提供了許多類庫,這些類庫的功能也十分強大,但對於一些Windows底層編程來說,還是要通過調用這些API函數纔可以實現。所有API都在"Kernel"、"User "和"GDI"三個庫中得以運行:其中"Kernel",他的庫名爲 "KERNEL32.DLL", 他主要用於產生與操作系統之間的關聯,譬如:程序加載,上下文選擇,文件輸入輸出,內存管理等等。"User "這個類庫在Win32中名叫 "USER32.DLL"。 它允許管理全部的用戶接口。譬如:窗口 、菜單 、對話框、圖標等等。"GDI"(圖象設備接口),它在Win32中的庫名爲:"GDI32.dll",它是圖形輸出庫。使用GDI Windows"畫"出窗口、菜單以及對話框等;它能創建圖形輸出;它也能保存圖形文件。由於本文所涉及到是圖象問題,所有調用的類庫是"GDI32.dll"。在本文程序中我們使用的API函數是"BitBlt",這個函數對於廣大程序員來說,一定不感覺到陌生,因爲在圖象處理方面他的用途是相對廣的,在用其他程序語言編程中,時常也要和他打交道。在.Net FrameWork SDK中有一個名字空間"System.Runtime.InteropServices",此名字空間提供了一系列的類來訪問COM對象,和調用本地的API函數。下面是在C#中聲明此函數:
[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
privatestaticexternbool BitBlt (
IntPtr hdcDest , // 目標 DC的句柄
int nXDest ,
int nYDest ,
int nWidth ,
int nHeight ,
IntPtr hdcSrc , // 源DC的句柄
int nXSrc ,
int nYSrc ,
System.Int32 dwRop // 光柵的處理數值
) ;
通過上面這個聲明,就可以在下面的代碼中使用此函數了。
下面是用C#做屏幕捕獲程序的具體實現步驟:
(1).首先要獲得當前屏幕的graphic對象,通過以下代碼可以實現:
Graphics g1 = this.CreateGraphics ( ) ;
(2).創建一個Bitmap對象,並且這個Bitmap對象的大小是當前屏幕:
首先要獲得當前屏幕的大小,通過名字空間"System.Windows.Forms"中的"Screen"類的GetWorkingArea()方法,可以實現。下面是得到當前屏幕的長(Height)和寬(Width):
Rectangle rect = new Rectangle ( ) ;
rect = Screen.GetWorkingArea ( this ) ;
"屏幕寬"= rect.Width ;
"屏幕長"= rect.Height ;
至此就可以得到我們想要的Bitmap了,通過下列語句可以實現:
Image MyImage = new Bitmap ( rect.Width , rect.Height , g1 ) ;
//創建以屏幕大小爲標準的位圖
(3).獲得當前屏幕和此Bitmap對象的DC,這可以通過下列語句實現:
//得到屏幕的DC
IntPtr dc1 = g1.GetHdc ( ) ;
//得到Bitmap的DC
IntPtr dc2 = g2.GetHdc ( ) ;
(4).調用API函數,把當前屏幕拷貝到創建的Bitmap中:
BitBlt ( dc2 , 0 , 0 , rect.Width , rect.Height , dc1 , 0 , 0 , 13369376 ) ;
(5).釋放當前屏幕和此Bitmap對象的DC,通過下面代碼可以實現:
//釋放掉屏幕的DC
g1.ReleaseHdc ( dc1 ) ;
//釋放掉Bitmap的DC
g2.ReleaseHdc ( dc2 ) ;
(6).保存Bitmap對象,形成jpg圖片:
MyImage.Save ( @"c:/Capture.jpg" , ImageFormat.Jpeg );
當然你也可以根據自己的需要,把屏幕以其他圖片的格式來保存,如果你想把圖片保存爲位圖文件,可以把"ImageFormat.Jpeg"改換成"ImageFormat.Bmp";想把圖片保存爲Gif文件,就把"ImageFormat.Jpeg"改換成"ImageFormat.Gif"。你可以保存的文件類型大概有十多種,這裏就不一一介紹了,當然你也要相應改變保存文件的後綴。
三. 用C#來捕獲屏幕的源程序代碼(Capture.cs):
瞭解上面的這些步驟的實現方法,就可以得到用C#捕獲屏幕的源程序,如下:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
namespace WindowsApplication3
...{
public partial class Form1 : Form
...{
private Button button1;
public Form1()
...{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
...{
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#捕獲當前屏幕!";
ResumeLayout(false);
}
//聲明一個API函數
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // 目標 DC的句柄
int nXDest,
int nYDest,
int nWidth,
int nHeight,
IntPtr hdcSrc, // 源DC的句柄
int nXSrc,
int nYSrc,
System.Int32 dwRop // 光柵的處理數值
);
private void button1_Click(object sender, System.EventArgs e)
...{
//獲得當前屏幕的大小
Rectangle rect = new Rectangle();
rect = Screen.GetWorkingArea(this);
//創建一個以當前屏幕爲模板的圖象
Graphics g1 = this.CreateGraphics();
//創建以屏幕大小爲標準的位圖
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();
//調用此API函數,實現屏幕捕獲
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("當前屏幕已經保存爲C盤的capture.jpg文件!");
}
}
}