使用C#制作屏幕捕捉程序
發(fā)表時間:2024-02-16 來源:明輝站整理相關軟件相關文章人氣:
[摘要] 隨著微軟.Net戰(zhàn)略的進一步深入,各種新的技術、概念可謂層出不窮,特別是C#語言的推出,在業(yè)界產生了重大影響。C#是一門高效的語言,它既有VB的RAD特性,又不乏C++語言的高效性。最重要的它是基于.Net Framework的,在圖形圖像、網絡編程等方面有著強大的優(yōu)勢,所以它很可能發(fā)展成為未...
隨著微軟.Net戰(zhàn)略的進一步深入,各種新的技術、概念可謂層出不窮,特別是C#語言的推出,在業(yè)界產生了重大影響。C#是一門高效的語言,它既有VB的RAD特性,又不乏C++語言的高效性。最重要的它是基于.Net Framework的,在圖形圖像、網絡編程等方面有著強大的優(yōu)勢,所以它很可能發(fā)展成為未來的主要編程語言之一。
本文通過一個實例來向大家展示一下用C#進行圖形圖像編程的特性。實例中運用到了GDI+編程的一些基礎知識,GDI+是從GDI演化而來的,是.Net環(huán)境下的新的圖形圖像編程機制。它不僅具有GDI編程的一些基本功能,而且對GDI進行了不少擴充,使得它功能更強大。在Visual Studio的以前版本中使用GDI是相當復雜的,而且工作量十分大。現在在GDI+中,微軟已經幫我們解決了許多問題,因而使用GDI+進行圖形圖像編程將變得非常容易。不過要指出的是:用GDI編程雖然較復雜,卻可以完成幾乎所有的復雜功能,比如在實例中用GDI可以輕易做一個屏幕捕捉程序。那么,現在我們在GDI+是否也能完成同樣的功能呢?答案是肯定的。正因為GDI+是從GDI演化而來的,我們只要在GDI+中調用GDI的一些功能就行了。
C#有一個特性,那就是它允許你運用任何預先已經完成的動態(tài)連接庫文件(*.dll),其中當然包括了gdi32.dll這個文件。該文件包含了進行GDI編程所需的基本類庫、函數、方法等。這樣,我們在GDI+編程機制下也同樣可以享受GDI為我們留下的寶貴資源。具體導入的方法如下:
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
在GDI中做屏幕捕捉程序的話,就要用到上下文設備(device context)了。在程序中,我們用它獲得屏幕圖形并將它寫入內存中的一個位圖中,實現的方法就是調用BitBlt()函數。同樣在GDI+中實現的原理是一樣的,下面給出了GDI+中的外部聲明函數(用C#語言描述):
privatestaticexternbool BitBlt(
IntPtr hdcDest, //目的上下文設備的句柄
int nXDest, //目的圖形的左上角的x坐標
int nYDest, //目的圖形的左上角的y坐標
int nWidth, //目的圖形的矩形寬度
int nHeight, //目的圖形的矩形高度
IntPtr hdcSrc, //源上下文設備的句柄
int nXSrc, //源圖形的左上角的x坐標
int nYSrc, //源圖形的左上角的x坐標
System.Int32 dwRop //光柵操作代碼
);
為了能在GDI+中調用GDI,我們還需要取得上下文設備的鉤子。在GDI+中有一個方法就提供了這種操作的具體實現:
IntPtr dc1 = aGraphicsObject.GetHdc();
在取得了源上下文設備以及目的上下文設備的句柄后,我們就可以在上面的BitBlt()函數運用它們(作為參數),實現圖像創(chuàng)建功能了。在圖像創(chuàng)建后,還必須釋放源上下文設備以及目的上下文設備資源。 這樣,基本的原理就已介紹完畢,總的來說實現的原理還是比較簡單的。下面就是實現實例的具體步驟:
1. 獲得一個對應于屏幕上窗體的圖形對象
2. 創(chuàng)建一個大小為窗體客戶區(qū)大小的位圖文件
3. 獲得窗體的上下文設備
4. 獲得位圖文件的上下文設備
5. 把屏幕上的窗體寫入位圖中
6. 釋放窗體的上下文設備
7. 釋放位圖文件的上下文設備
8. 將圖像保存為一個jpeg格式的文件
工程步驟:
1. 新建一個C#的工程,不妨命名為“FormCapture”,圖示如下:
2. 布置主窗體:
在窗體上添加一個圖片框(pictureBox)控件以及一個按鈕(button)控件即可。將主窗體的Text屬性設置為“屏幕捕捉程序”;將圖片框的Image屬性設置為一個圖形文件;將按鈕的Text屬性設置為“屏幕捕捉”即可。(當然讀者可以添加自己需要的控件來布置主窗體)圖示如下:
3. 代碼編寫:
先在代碼文件中添加上面介紹的BitBlt函數的外部聲明。
再添加按鈕的OnClick事件處理函數,該函數就是實現屏幕捕捉的主要部分了。函數如下:
private void button1_Click(object sender, System.EventArgs e)
{
Graphics g1 = this.CreateGraphics();//獲得窗體圖形對象
Image MyImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);//創(chuàng)建位圖圖形對象
IntPtr dc1 = g1.GetHdc();//獲得窗體的上下文設備
IntPtr dc2 = g2.GetHdc();//獲得位圖文件的上下文設備
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);//寫入到位圖
g1.ReleaseHdc(dc1);//釋放窗體的上下文設備
g2.ReleaseHdc(dc2);//釋放位圖文件的上下文設備
MyImage.Save(@"c:\Captured.jpg", ImageFormat.Jpeg);//保存為jpeg文件
MessageBox.Show("保存圖片結束!");
}
4.到此為止,程序已經做完了。按Ctrl+F5可以試試效果如下圖:
圖片已經保存好了,看看屏幕捕捉的結果吧(如下圖)!
不過,這個程序只是捕捉到了程序自身的客戶區(qū),所以功能有限。當然,你也可以試著做個捕捉屏幕任何位置的程序!你只要改變源圖像的寬度和高度即可,而這個寬度和高度當然可以由用戶來選定。這樣,一個自制的屏幕捕捉程序就出爐了。
從上面的實例中,我們不難發(fā)現用C#編程實現一些基本功能還是非常容易的,真可謂是高效開發(fā)的好工具。所以,筆者希望有更多的人加入C#的行列,開發(fā)出更實用、更完善的軟件。 完整代碼:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
namespace FormCapture
{
///
/// Summary description for Form1.
///
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button button1;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
this.button1 = new System.Windows.Forms.Button();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.SuspendLayout();
//
// button1
//
this.button1.BackColor = System.Drawing.SystemColors.ActiveBorder;
this.button1.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
this.button1.Location = new System.Drawing.Point(272, 19);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(72, 27);
this.button1.TabIndex = 4;
this.button1.Text = "屏幕捕捉";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Bitmap)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(16, 16);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(240, 224);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(358, 255);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.button1,
this.pictureBox1});
this.KeyPreview = true;
this.Name = "Form1";
this.Text = "屏幕捕捉程序";
this.ResumeLayout(false);
}
#endregion
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, //目的DC的句柄
int nXDest, //目的圖形的左上角的x坐標
int nYDest, //目的圖形的左上角的y坐標
int nWidth, //目的圖形的矩形寬度
int nHeight, //目的圖形的矩形高度
IntPtr hdcSrc, //源DC的句柄
int nXSrc, //源圖形的左上角的x坐標
int nYSrc, //源圖形的左上角的x坐標
System.Int32 dwRop //光柵操作代碼
);
private void button1_Click(object sender, System.EventArgs e)
{
Graphics g1 = this.CreateGraphics();//獲得窗體圖形對象
Image MyImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);//創(chuàng)建位圖圖形對象
IntPtr dc1 = g1.GetHdc();//獲得窗體的上下文設備
IntPtr dc2 = g2.GetHdc();//獲得位圖文件的上下文設備
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);//寫入到位圖
g1.ReleaseHdc(dc1);//釋放窗體的上下文設備
g2.ReleaseHdc(dc2);//釋放位圖文件的上下文設備
MyImage.Save(@"c:\Captured.jpg", ImageFormat.Jpeg);//保存為jpeg文件
MessageBox.Show("保存圖片結束!");
}
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
} (出處:eNet硅谷動力)