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#截屏实现的主要内容,如果未能解决你的问题,请参考以下文章

Winform C#截屏实现

Winform C#截屏实现

C#截屏

C# winform 中C/S结构,客户端怎么获取截屏,获取图片,把图片保存到服务器图片文件夹里面?

WinForm C# 获取屏幕真实分辨率

WinForm C# 获取屏幕真实分辨率