解決C#全螢幕截圖的實現方法

來源:互聯網
上載者:User

今天一位同事想寫一個全螢幕的代碼。當然要實現的第一步是能夠擷取整個螢幕的位元影像,記得Win32 API的CreateDC, BitBlt等函數可以使用。於是上網查了下,果然螢幕用這些函數。但winform已經可以把API都忘記了,所以得尋找一個無Win32 API的實現方式。綜合了網上的實現,以及自己的一些設計,實現思路如下:
1. 開始時,建立一個與螢幕大小一樣的位元影像,然後用Graphics.CopyFromScreen()把螢幕位元影像拷貝到該位元影像上。這是很關鍵的一步,這樣所有的操作就都可以在該位元影像上進行了,而無實際螢幕無關了。
複製代碼 代碼如下:Code
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. 接下來為了方便在這之上進行,有一個很重要的設計實現方式:用全螢幕表單代替現有真實螢幕,這樣就可以把過程的所有操作都在那個表單上實現(該表單設定成無邊框,高寬等於螢幕大小即可),另外為了顯示掩蔽效果(只能正常顯示選擇的部分螢幕內容,而其實部分用一個如半透明層覆蓋),就添加一層半透明位置位元影像。具體代碼如下:
複製代碼 代碼如下:Code
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,它自動會形成一個中空的地區。上面的實現很容易擴充:多地區,多裁判等都很容易實現。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.