使用C#制作屏幕捕捉程序
發(fā)表時間:2024-06-12 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]隨著微軟.Net戰(zhàn)略的進(jìn)一步深入,各種新的技術(shù)、概念可謂層出不窮,特別是C#語言的推出,在業(yè)界產(chǎn)生了重大影響。C#是一門高效的語言,它既有VB的RAD特性,又不乏C++語言的高效性。最重要的它是基于.Net Framework的,在圖形圖像、網(wǎng)絡(luò)編程等方面有著強(qiáng)大的優(yōu)勢,所以它很可能發(fā)展成為未...
隨著微軟.Net戰(zhàn)略的進(jìn)一步深入,各種新的技術(shù)、概念可謂層出不窮,特別是C#語言的推出,在業(yè)界產(chǎn)生了重大影響。C#是一門高效的語言,它既有VB的RAD特性,又不乏C++語言的高效性。最重要的它是基于.Net Framework的,在圖形圖像、網(wǎng)絡(luò)編程等方面有著強(qiáng)大的優(yōu)勢,所以它很可能發(fā)展成為未來的主要編程語言之一。
本文通過一個實(shí)例來向大家展示一下用C#進(jìn)行圖形圖像編程的特性。實(shí)例中運(yùn)用到了GDI+編程的一些基礎(chǔ)知識,GDI+是從GDI演化而來的,是.Net環(huán)境下的新的圖形圖像編程機(jī)制。它不僅具有GDI編程的一些基本功能,而且對GDI進(jìn)行了不少擴(kuò)充,使得它功能更強(qiáng)大。在Visual Studio的以前版本中使用GDI是相當(dāng)復(fù)雜的,而且工作量十分大,F(xiàn)在在GDI+中,微軟已經(jīng)幫我們解決了許多問題,因而使用GDI+進(jìn)行圖形圖像編程將變得非常容易。不過要指出的是:用GDI編程雖然較復(fù)雜,卻可以完成幾乎所有的復(fù)雜功能,比如在實(shí)例中用GDI可以輕易做一個屏幕捕捉程序。那么,現(xiàn)在我們在GDI+是否也能完成同樣的功能呢?答案是肯定的。正因?yàn)镚DI+是從GDI演化而來的,我們只要在GDI+中調(diào)用GDI的一些功能就行了。
C#有一個特性,那就是它允許你運(yùn)用任何預(yù)先已經(jīng)完成的動態(tài)連接庫文件(*.dll),其中當(dāng)然包括了gdi32.dll這個文件。該文件包含了進(jìn)行GDI編程所需的基本類庫、函數(shù)、方法等。這樣,我們在GDI+編程機(jī)制下也同樣可以享受GDI為我們留下的寶貴資源。具體導(dǎo)入的方法如下:
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
在GDI中做屏幕捕捉程序的話,就要用到上下文設(shè)備(device context)了。在程序中,我們用它獲得屏幕圖形并將它寫入內(nèi)存中的一個位圖中,實(shí)現(xiàn)的方法就是調(diào)用BitBlt()函數(shù)。同樣在GDI+中實(shí)現(xiàn)的原理是一樣的,下面給出了GDI+中的外部聲明函數(shù)(用C#語言描述):
privatestaticexternbool BitBlt(
IntPtr hdcDest, //目的上下文設(shè)備的句柄
int nXDest, //目的圖形的左上角的x坐標(biāo)
int nYDest, //目的圖形的左上角的y坐標(biāo)
int nWidth, //目的圖形的矩形寬度
int nHeight, //目的圖形的矩形高度
IntPtr hdcSrc, //源上下文設(shè)備的句柄
int nXSrc, //源圖形的左上角的x坐標(biāo)
int nYSrc, //源圖形的左上角的x坐標(biāo)
System.Int32 dwRop //光柵操作代碼
);
為了能在GDI+中調(diào)用GDI,我們還需要取得上下文設(shè)備的鉤子。在GDI+中有一個方法就提供了這種操作的具體實(shí)現(xiàn):
IntPtr dc1 = aGraphicsObject.GetHdc();
在取得了源上下文設(shè)備以及目的上下文設(shè)備的句柄后,我們就可以在上面的BitBlt()函數(shù)運(yùn)用它們(作為參數(shù)),實(shí)現(xiàn)圖像創(chuàng)建功能了。在圖像創(chuàng)建后,還必須釋放源上下文設(shè)備以及目的上下文設(shè)備資源。 這樣,基本的原理就已介紹完畢,總的來說實(shí)現(xiàn)的原理還是比較簡單的。下面就是實(shí)現(xiàn)實(shí)例的具體步驟:
1. 獲得一個對應(yīng)于屏幕上窗體的圖形對象
2. 創(chuàng)建一個大小為窗體客戶區(qū)大小的位圖文件
3. 獲得窗體的上下文設(shè)備
4. 獲得位圖文件的上下文設(shè)備
5. 把屏幕上的窗體寫入位圖中
6. 釋放窗體的上下文設(shè)備
7. 釋放位圖文件的上下文設(shè)備
8. 將圖像保存為一個jpeg格式的文件
工程步驟:
1. 新建一個C#的工程,不妨命名為“FormCapture”,圖示如下:
2. 布置主窗體:
在窗體上添加一個圖片框(pictureBox)控件以及一個按鈕(button)控件即可。將主窗體的Text屬性設(shè)置為“屏幕捕捉程序”;將圖片框的Image屬性設(shè)置為一個圖形文件;將按鈕的Text屬性設(shè)置為“屏幕捕捉”即可。(當(dāng)然讀者可以添加自己需要的控件來布置主窗體)圖示如下:
3. 代碼編寫:
先在代碼文件中添加上面介紹的BitBlt函數(shù)的外部聲明。
再添加按鈕的OnClick事件處理函數(shù),該函數(shù)就是實(shí)現(xiàn)屏幕捕捉的主要部分了。函數(shù)如下:
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();//獲得窗體的上下文設(shè)備
IntPtr dc2 = g2.GetHdc();//獲得位圖文件的上下文設(shè)備
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);//寫入到位圖
g1.ReleaseHdc(dc1);//釋放窗體的上下文設(shè)備
g2.ReleaseHdc(dc2);//釋放位圖文件的上下文設(shè)備
MyImage.Save(@"c:\Captured.jpg", ImageFormat.Jpeg);//保存為jpeg文件
MessageBox.Show("保存圖片結(jié)束!");
}
4.到此為止,程序已經(jīng)做完了。按Ctrl+F5可以試試效果如下圖:
圖片已經(jīng)保存好了,看看屏幕捕捉的結(jié)果吧(如下圖)!
不過,這個程序只是捕捉到了程序自身的客戶區(qū),所以功能有限。當(dāng)然,你也可以試著做個捕捉屏幕任何位置的程序!你只要改變源圖像的寬度和高度即可,而這個寬度和高度當(dāng)然可以由用戶來選定。這樣,一個自制的屏幕捕捉程序就出爐了。
從上面的實(shí)例中,我們不難發(fā)現(xiàn)用C#編程實(shí)現(xiàn)一些基本功能還是非常容易的,真可謂是高效開發(fā)的好工具。所以,筆者希望有更多的人加入C#的行列,開發(fā)出更實(shí)用、更完善的軟件。 完整代碼:
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坐標(biāo)
int nYDest, //目的圖形的左上角的y坐標(biāo)
int nWidth, //目的圖形的矩形寬度
int nHeight, //目的圖形的矩形高度
IntPtr hdcSrc, //源DC的句柄
int nXSrc, //源圖形的左上角的x坐標(biāo)
int nYSrc, //源圖形的左上角的x坐標(biāo)
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();//獲得窗體的上下文設(shè)備
IntPtr dc2 = g2.GetHdc();//獲得位圖文件的上下文設(shè)備
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);//寫入到位圖
g1.ReleaseHdc(dc1);//釋放窗體的上下文設(shè)備
g2.ReleaseHdc(dc2);//釋放位圖文件的上下文設(shè)備
MyImage.Save(@"c:\Captured.jpg", ImageFormat.Jpeg);//保存為jpeg文件
MessageBox.Show("保存圖片結(jié)束!");
}
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
} (出處:eNet硅谷動力)