程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 用C#實現全屏幕截圖

用C#實現全屏幕截圖

編輯:C#入門知識

今天一位同事想寫一個全屏幕截圖的代碼。當然要實現的第一步是能夠獲取整個屏幕的位圖,記得Win32 API的CreateDC, BitBlt等函數可以使用。於是上網查了下,果然屏幕截圖用這些函數。但winform已經可以把API都忘記了,所以得尋找一個無Win32 API的實現方式。綜合了網上的實現,以及自己的一些設計,實現思路如下:1. 開始截圖時,創建一個與屏幕大小一樣的位圖,然後用Graphics.CopyFromScreen()把屏幕位圖拷貝到該位圖上。這是很關鍵的一步,這樣所有的操作就都可以在該位圖上進行了,而無實際屏幕無關了。
    int width = Screen.PrimaryScreen.Bounds.Width;

    int height = Screen.PrimaryScreen.Bounds.Height;

    Bitmap bmp = new Bitmap(width, height);

    using (Graphics g = Graphics.FromImage(bmp)) {

    g.CopyFromScreen(0, 0, 0, 0, new Size(width, height));

    }

    2. 接下來為了方便在這之上進行截圖,有一個很重要的設計實現方式:用全屏幕窗體代替現有真實屏幕,這樣就可以把截圖過程的所有操作都在那個窗體上實現(該窗體設置成無邊框,高寬等於屏幕大小即可),另外為了顯示掩蔽效果(只能正常顯示選擇的部分屏幕內容,而其實部分用一個如半透明層覆蓋),就添加一層半透明位置位圖。具體代碼如下:

    public partial class FullScreenForm : Form {

    private Rectangle rectSelected = Rectangle.Empty;

    private bool isClipping = false;

    private Bitmap screen;

    private Bitmap coverLayer = null;

    private Color coverColor;

    private Brush rectBrush = null;

    private Bitmap resultBmp = null;

    public FullScreenForm(Bitmap screen) {

    InitializeComponent();

    int width = Screen.PrimaryScreen.Bounds.Width;

    int height = Screen.PrimaryScreen.Bounds.Height;

    coverLayer = new Bitmap(width, height);

    coverColor = Color.FromArgb(50, 200, 0, 0);

    rectBrush = new SolidBrush(coverColor);

    using (Graphics g = Graphics.FromImage(coverLayer)) {

    g.Clear(coverColor);

    }

    this.Bounds = new Rectangle(0, 0, width, height);

    this.screen = screen;

    this.DoubleBuffered = true;

    }

    protected override void OnMouseDown(MouseEventArgs e) {

    if (e.Button == MouseButtons.Left) {

    isClipping = true;

    rectSelected.Location = e.Location;

    }

    else if (e.Button == MouseButtons.Right) {

    this.DialogResult = DialogResult.OK;

    }

    }

    protected override void OnMouseMove(MouseEventArgs e) {

    if (e.Button == MouseButtons.Left & & isClipping) {

    rectSelected.Width = e.X - rectSelected.X;

    rectSelected.Height = e.Y - rectSelected.Y;

    this.Invalidate();

    }

    }

    protected override void OnMouseUp(MouseEventArgs e) {

    if (e.Button == MouseButtons.Left && isClipping) {

    rectSelected.Width = e.X - rectSelected.X;

    rectSelected.Height = e.Y - rectSelected.Y;

    this.Invalidate();

    resultBmp = new Bitmap(rectSelected.Width, rectSelected.Height);

    using (Graphics g = Graphics.FromImage(resultBmp)) {

    g.DrawImage(screen,new Rectangle(0, 0, rectSelected.Width, rectSelected.Height), rectSelected, GraphicsUnit.Pixel);

    }

    this.DialogResult = DialogResult.OK;

    }

    }

    protected override void OnPaint(PaintEventArgs e) {

    Graphics g = e.Graphics;

    g.DrawImage(screen, 0, 0);

    g.DrawImage(coverLayer, 0, 0);

    PaintRectangle();

    }

    protected override void OnPaintBackground(PaintEventArgs e) {

    }

    protected override void OnKeyDown(KeyEventArgs e) {

    if (e.KeyCode == Keys.Escape) {

    this.DialogResult = DialogResult.Cancel;

    }

    }

    private void PaintRectangle() {

    using (Graphics g = Graphics.FromImage(coverLayer)) {

    g.Clear(coverColor);

    GraphicsPath path = new GraphicsPath();

    path.AddRectangle(this.Bounds);

    path.AddRectangle(rectSelected);

    g.FillPath(rectBrush, path);

    g.DrawRectangle(Pens.Blue, rectSelected);

    }

    }

    public Bitmap ResultBitmap {

    get { return resultBmp; }

    }

    }

    上面的代碼都很容易看明白,這裡有一個技巧就是GraphicsPath,它自動會形成一個中空的區域。上面的實現很容易擴展:多區域截圖,多裁判截圖等都很容易實現。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved