Winform C#截屏实现
Posted T20140401
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Winform C#截屏实现相关的知识,希望对你有一定的参考价值。
项目中需要实现自动截取屏幕,网络上找了好久,发现好可以达到效果的程序,太复杂。代码少的程序,截屏时的效果并不太理想。综合网上的程序,略做改动,记录如下。
实现思路:
1.新建一个form窗体,FormStyle为None,初始化时最大化,作为截屏的画布。
2.实现按键监听事件,响应ESC退出
3.实现Mouse Down、Up、Move事件,实现截取退出截屏等操作。
下面直接上代码,关键部分,看注释。代码上传时,有改动,未调试,可能有问题,主要是记录实现思路。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Test_Screen_Capture
public partial class ScreenCapture : Form
public ScreenCapture()
InitializeComponent();
private Image _back get; set;
private bool _downed get; set;
private Image _image get; set;
public Image selected_image get; set;
public Rectangle rect get; set;
private Point _down_point get; set;
private SolidBrush _mask get; set;
protected override void OnPaint(PaintEventArgs e)
base.OnPaint(e);
Graphics org = e.Graphics; //画出选择区域
org.DrawImage(_image, rect, rect, GraphicsUnit.Pixel);
Graphics g = e.Graphics;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
if (rect.Width != 0 && rect.Height != 0)
if (is_downed)
using (Pen pen = new Pen(Brushes.Red))
g.DrawRectangle(pen, rect);
/// <summary>
/// 获取屏幕真实分辨率
/// </summary>
/// <returns></returns>
public static Size get_real_size_of_screen()
int w = Screen.PrimaryScreen.Bounds.Width;
int h = Screen.PrimaryScreen.Bounds.Height;
Bitmap b = new Bitmap(w * 3, h * 3);
Graphics g = Graphics.FromImage(b);
g.CopyFromScreen(0, 0, 0, 0, b.Size);
g.Dispose();
GC.Collect();
for (var iW = 1; iW < w * 3 - 1; iW++)
Color c = b.GetPixel(iW, 0);
if (c == 0 && c == 0 && c == 0 && c == 0)
w = iW;
break;
//h应当以同样的方式获取,懒得改了
if (Screen.PrimaryScreen.Bounds.Width != w)
h = Convert.ToInt32(Screen.PrimaryScreen.Bounds.Height * w / Screen.PrimaryScreen.Bounds.Width);
Size size = new Size(w, h);
return size;
public static Image get_desktop_image()//获取屏幕背景
Size s = get_real_size_of_screen();
System.Drawing.Rectangle r = new System.Drawing.Rectangle(0, 0, s.Width, s.Height);
Bitmap bitmap = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(bitmap))
g.CopyFromScreen(0, 0, 0, 0, r.Size);
double scale = Screen.PrimaryScreen.Bounds.Width / (double)s.Width;
return scale_image(bitmap, scale);//返回当前分辨率对应的图像
/// <summary>
/// 缩放图片
/// </summary>
/// <param name="org"></param>
/// <param name="scale"></param>
/// <returns></returns>
public static Bitmap scale_image(Bitmap org, double scale)
int w = (int)(org.Width * scale);
int h = (int)(org.Height * scale);
Bitmap _out = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(_out))
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.DrawImage(org, new Rectangle(0, 0, w, h), new Rectangle(0, 0, org.Width, org.Height), GraphicsUnit.Pixel);
return _out;
//计算用户选取的矩形区域
private Rectangle get_rectangle(int _x, int _y)
int w = Math.Abs(down_point.X - _x);
int h = Math.Abs(down_point.Y - _y);
Rectangle r = new Rectangle();
r.X = down_point.X > _x ? _x : down_point.X;
r.Y = down_point.Y > _y ? _y : down_point.Y;
r.Size = new Size(w, h);
return r;
private void ScreenCapture_KeyDown(object sender, KeyEventArgs e)
if (e.KeyCode == Keys.Escape)
this.Close();
private void ScreenCapture_MouseDown(object sender, MouseEventArgs e)
if (e.Button == MouseButtons.Left)
is_downed = true;
down_point = new Point(e.X, e.Y);
if (e.Button == MouseButtons.Right)
this.Close();
private void ScreenCapture_MouseMove(object sender, MouseEventArgs e)
if (_downed)
this.Refresh();
rect = get_rectangle(e.X, e.Y);
private void ScreenCapture_MouseUp(object sender, MouseEventArgs e)
if (e.Button == MouseButtons.Left)
_downed = false;
if (rect.Width != 0 && rect.Height != 0)
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(bmp))
g.DrawImage(_image, 0, 0, rect, GraphicsUnit.Pixel);
g.Flush();
selected_image = bmp;//截取区域,可以直接设定路径保存图片
this.Close();
private void ScreenCapture_Load(object sender, EventArgs e)
this.DoubleBuffered = true;//开启双缓冲模式,防止屏幕闪烁
this.WindowState = FormWindowState.Maximized;
_downed = false;
_image = get_desktop_image();
rect = new Rectangle();
_back = new Bitmap(_image);
//遮罩
_mask = new SolidBrush(Color.FromArgb(120, 240, 240, 240));
using (Graphics g = Graphics.FromImage(_back))
g.FillRectangle(mask, 0, 0, _back_screen.Width, _back_screen.Height);
this.BackgroundImage = _back;
以上是关于Winform C#截屏实现的主要内容,如果未能解决你的问题,请参考以下文章