当前位置:编程学习 > C#/ASP.NET >>

自己写的C#截图工具

自学C#差不多一星期,之前大一学习过C和C++,之后接触过学校组织的一星期java实习培训,想了想选择C#了。这几天宅宿舍天天写,参考各种资料终于写成了这个截图工具。跟QQ截图很像,不过没有自动选框功能和截图后涂鸦编辑功能。新手代码很乱。。附上核心代码。完整工程文件和源代码见这里  http://download.csdn.net/detail/justlovediaodaio/4620457
环境VS2012 For Desktop,NetFramework4.5.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CatchScreen
{
    //定义委托
    public delegate void SetICS(bool isCatchScreen);
    public partial class Catch : Form
    {
        //鼠标位置的枚举
        private enum MouseLocation
        {
            LeftUpPoint,LeftDownPoint,RightUpPoint,RightDownPoint,LeftLine,RightLine,UpLine,DownLine,
            InRectangle,OutOfRectangle
        }
        private MouseLocation mouseLocation;
        //定义该委托的事件
        public event SetICS SetICSEvent;
        //截屏原始图片
        private Bitmap originBmp;
        //鼠标左键按下的坐标
        private Point mouseDownPoint;
        //调节截图框时的固定不动点
        private Point fixedPoint;
        //是否允许绘制矩形截图状态
        private bool isDraw;
        //截图完成状态
        private bool isCatched;
        //是否允许调节矩形框
        private bool isAdjust;
        //绘制的截图矩形框
        private Rectangle rect;
        public Catch()
        {
            InitializeComponent();
        }
        //将当前屏幕截图,显示到全屏无标题栏窗体上
        private void Catch_Load(object sender, EventArgs e)
        {
            //设置截图状态为开始
            SetICSEvent(true);
            //隐藏窗体,保证截屏图片为当前屏幕而不是被窗体覆盖
            this.Hide();
            //以当前窗口大小(窗口默认最大化,即全屏)创建截屏空白图片
            this.originBmp = new Bitmap(this.Width,this.Height );
            //以截屏图片作为画板
            using (Graphics gs = Graphics.FromImage(originBmp))
            {
                //复制当前屏幕到画板上,即将截屏图片的内容设置为当前屏幕
                gs.CopyFromScreen(0, 0, 0, 0, this.Size);
            }
            //将截屏图片设为窗体背景
            this.BackgroundImage = new Bitmap(this.originBmp);
            //添加截屏时的黑色遮罩,即在窗体背景上绘制全屏半透明黑色填充矩形
            using (Graphics blackgs = Graphics.FromImage(this.BackgroundImage))
            {
                using (SolidBrush backBrush = new SolidBrush(Color.FromArgb(100, 0, 0, 0)))
                {
                    blackgs.FillRectangle(backBrush, 0, 0, this.Width, this.Height);
                }
            }
            //显示窗体
            this.Show();
            //激活当前窗体,使之具有焦点。主要针对win8 Metro界面的截图。
            this.Activate();
        }
        //右键点击动作
        private void Catch_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                //开始绘制矩形框前,即初始状态,直接退出截图
                if (isCatched == false)
                {
                    this.Close();
                }
                //若矩形框已绘制,设定状态为初始状态,设定矩形各参数为0,
                //刷新窗体重绘,以清除已绘制的矩形,重新开始截图,即撤销功能。
                else
                {
                    this.isCatched = false;
                    this.isAdjust = false;
                    this.isDraw = false;
                    this.rect = new Rectangle(0, 0, 0, 0);
                    this.Refresh();
                }
            }
        }
        //鼠标左键按下开始截图
        private void Catch_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                //未捕获时,设定状态为允许绘制矩形
                if (isCatched == false)
                {
                    this.isDraw = true;
                    
                }
                else
                {
                    //捕获完成后在矩形框内按下左键,设置状态为调节矩形框位置和大小
                    //为方便使用,矩形框内外以及边和顶点的判定都为目标附近
                    if (MousePosition.X > rect.Left - 3 && MousePosition.X < rect.Right + 3
                        && MousePosition.Y > rect.Top - 3 && MousePosition.Y < rect.Bottom + 3)
                    {
                        this.isAdjust = true;
                    }
                }
                //记下鼠标左键按下的坐标,设置显示光标
                this.CursorLocation();
                this.mouseDownPoint = new Point(e.X, e.Y);
            }
        }
        
        private void Catch_MouseMove(object sender, MouseEventArgs e)
        {
            //移动鼠标绘制矩形
            if (this.isDraw == true)
            {
                //鼠标按下并移动设定状态为已捕获
                this.isCatched = true;
                //记录矩形左上角点的坐标
                Point leftUpPoint = new Point(this.mouseDownPoint.X, this.mouseDownPoint.Y);
                if (e.X < this.mouseDownPoint.X)
                    leftUpPoint.X = e.X;
                if (e.Y < this.mouseDownPoint.Y)
                    leftUpPoint.Y = e.Y;
                //获取矩形的长和宽
                int wideth = Math.Abs(this.mouseDownPoint.X - e.X);
                int height = Math.Abs(this.mouseDownPoint.Y - e.Y);
                //防止分辨率为0的截图区域
                if (wideth == 0)
                    ++wideth;
                if (height == 0)
                    ++height;
                //记录绘制的矩形
                this.rect = new Rectangle(leftUpPoint.X, leftUpPoint.Y, wideth, height);
                //刷新窗体,以触发OnPain事件重绘窗体
                this.Refresh();
                
            }
            //调节矩形框
            else
            {
                if (isCatched == true)
                {
                    //捕获完成,按下左键前显示当鼠标在矩形框上时的形状
                    if (isAdjust == false)
                    {
                        this.CursorLocation();
                    }
                    else
                    {
                        //计算调节矩形框的大小和位置
                        Point leftUpPoint = new Point(this.fixedPoint.X, this.fixedPoint.Y);
                        if (e.X < this.fixedPoint.X)
                            leftUpPoint.X = e.X;
                        if (e.Y < this.fixedPoint.Y)
                            leftUpPoint.Y = e.Y;
                        int wideth = Math.Abs(this.fixedPoint.X - e.X);
                        int height = Math.Abs(this.fixedPoint.Y - e.Y);
                        switch (mouseLocation)
                        {
                            //校正以上计算的矩形框位置以及大小
                            case MouseLocation.InRectangle:
                                leftUpPoint.X = this.fixedPoint.X + e.X - this.mouseDownPoint.X;
                                leftUpPoint.Y = this.fixedPoint.Y + e.Y - this.mouseDownPoint.Y;
                                wideth = this.rect.Width;
                                height = this.rect.Height;
                                //防止矩形框移出屏幕外
                                if (leftUpPoint.X < 0)
                                    leftUpPoint.X = 0;
                                if (leftUpPoint.Y < 0)
                                    leftUpPoint.Y = 0;
                                if (leftUpPoint.X + wideth >= this.Width)
                                    leftUpPoint.X = this.Width - wideth-1;
                                if (leftUpPoint.Y + height >= this.Height)
                                    leftUpPoint.Y = this.Height - height-1;
                                break;
                            case MouseLocation.LeftLine:
                            case MouseLocation.RightLine:
                                leftUpPoint.Y = this.rect.Y;
                                height = this.rect.Height;
                                break;
                            case MouseLocation.UpLine:
                            case MouseLocation.DownLine:
                                leftUpPoint.X = this.rect.X;
                                wideth = this.rect.Width;
                                break;
                        }
                        //防止分辨率为0的截图区域
                        if (wideth == 0)
                            ++wideth;
                        if (height == 0)
                            ++height;
                        //改变矩形框,刷新重绘
                        this.rect = new Rectangle(leftUpPoint.X,leftUpPoint.Y, wideth, height);
                        this.Refresh();
                    }
                }
            }
        }
--------------------编程问答--------------------

        //重载OnPaint事件,窗体每次重绘所调用的函数
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            //防止窗体第一次显示时绘出分辨率显示
            if (this.rect.Width != 0)
            {
                //向窗体添加画板,绘制矩形
                Graphics gs = e.Graphics;
                //绘制截屏图片上的矩形框选中部分到当前画板上的矩形框部分,以覆盖黑色遮罩
                gs.DrawImage(this.originBmp, this.rect, this.rect, GraphicsUnit.Pixel);
                //定义画笔
                using (Pen linePen = new Pen(Color.FromArgb(255,0,174,255), 1))
                {
                    //绘制矩形
                    gs.DrawRectangle(linePen, this.rect);
                    //绘出线条上的点
                    using (SolidBrush pointBrush = new SolidBrush(Color.FromArgb(255, 0, 174, 255)))
                    {
                        //顶点
                        gs.FillRectangle(pointBrush, this.rect.X - 2, this.rect.Y - 2, 4,4 );
                        gs.FillRectangle(pointBrush, this.rect.Right - 2, this.rect.Y - 2, 4, 4);
                        gs.FillRectangle(pointBrush, this.rect.X - 2, this.rect.Bottom - 2, 4, 4);
                        gs.FillRectangle(pointBrush, this.rect.Right - 2, this.rect.Bottom - 2, 4, 4);
                        //中点
                        gs.FillRectangle(pointBrush, this.rect.X - 2, (this.rect.Y + this.rect.Bottom)/2 - 2, 4, 4);
                        gs.FillRectangle(pointBrush, (this.rect.X + this.rect.Right)/2 - 2, this.rect.Y - 2, 4, 4);
                        gs.FillRectangle(pointBrush, (this.rect.X + this.rect.Right)/2 - 2, this.rect.Bottom - 2, 4, 4);
                        gs.FillRectangle(pointBrush, this.rect.Right - 2, (this.rect.Y + this.rect.Bottom)/2 - 2, 4, 4);
                    }
                }
                //定义分辨率文字显示背景画刷,ARGB值。
                using (SolidBrush backBrush = new SolidBrush(Color.FromArgb(150, 0, 0, 0)))
                {
                    //绘制分辨率文字背景
                    //靠近屏幕上方和右边缘调整背景绘图位置,避免超出屏幕范围
                    if (this.rect.Y < 16)
                    {
                        if(this.rect.X + 70 > this.Width - 71)
                            gs.FillRectangle(backBrush,this.rect.X - 71,this.rect.Y,70,15);
                        else
                            gs.FillRectangle(backBrush, this.rect.X, this.rect.Y, 70, 15);
                    }
                    else
                    {
                        if(this.rect.X > this.Width - 71)
                            gs.FillRectangle(backBrush,this.rect.X - 71,this.rect.Y - 16,70,15);
                        else
                            
                            gs.FillRectangle(backBrush, this.rect.X, this.rect.Y - 16, 70, 15);
                    }
                }
                //定义绘制文字字体
                using (Font drawFont = new Font("Arial", 9))
                {
                    //定义分辨率文字画刷
                    using (SolidBrush drawBrush = new SolidBrush(Color.White))
                    {
                        //获取分辨率文字
                        string ratio = this.rect.Width.ToString() + " x " + rect.Height.ToString();
                        //绘制分辨率文字
                        if (this.rect.Y < 16)
                        {
                            if(this.rect.X > this.Width - 71)
                                gs.DrawString(ratio,drawFont,drawBrush,new Point (this.rect.X - 71,this.rect.Y));
                            else
                                gs.DrawString(ratio, drawFont, drawBrush, new Point(this.rect.X, this.rect.Y));
                        }
                        else
                        {
                            if(this.rect.X > this.Width - 71)
                                gs.DrawString(ratio,drawFont,drawBrush,new Point(this.rect.X - 71,this.rect.Y - 16));
                            else
                                gs.DrawString(ratio, drawFont, drawBrush, new Point(this.rect.X, this.rect.Y - 16));
                        }
                    }
                }
            } 
        }


        
--------------------编程问答--------------------

            

        //重载OnPaint事件,窗体每次重绘所调用的函数
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            //防止窗体第一次显示时绘出分辨率显示
            if (this.rect.Width != 0)
            {
                //向窗体添加画板,绘制矩形
                Graphics gs = e.Graphics;
                //绘制截屏图片上的矩形框选中部分到当前画板上的矩形框部分,以覆盖黑色遮罩
                gs.DrawImage(this.originBmp, this.rect, this.rect, GraphicsUnit.Pixel);
                //定义画笔
                using (Pen linePen = new Pen(Color.FromArgb(255,0,174,255), 1))
                {
                    //绘制矩形
                    gs.DrawRectangle(linePen, this.rect);
                    //绘出线条上的点
                    using (SolidBrush pointBrush = new SolidBrush(Color.FromArgb(255, 0, 174, 255)))
                    {
                        //顶点
                        gs.FillRectangle(pointBrush, this.rect.X - 2, this.rect.Y - 2, 4,4 );
                        gs.FillRectangle(pointBrush, this.rect.Right - 2, this.rect.Y - 2, 4, 4);
                        gs.FillRectangle(pointBrush, this.rect.X - 2, this.rect.Bottom - 2, 4, 4);
                        gs.FillRectangle(pointBrush, this.rect.Right - 2, this.rect.Bottom - 2, 4, 4);
                        //中点
                        gs.FillRectangle(pointBrush, this.rect.X - 2, (this.rect.Y + this.rect.Bottom)/2 - 2, 4, 4);
                        gs.FillRectangle(pointBrush, (this.rect.X + this.rect.Right)/2 - 2, this.rect.Y - 2, 4, 4);
                        gs.FillRectangle(pointBrush, (this.rect.X + this.rect.Right)/2 - 2, this.rect.Bottom - 2, 4, 4);
                        gs.FillRectangle(pointBrush, this.rect.Right - 2, (this.rect.Y + this.rect.Bottom)/2 - 2, 4, 4);
                    }
                }
                //定义分辨率文字显示背景画刷,ARGB值。
                using (SolidBrush backBrush = new SolidBrush(Color.FromArgb(150, 0, 0, 0)))
                {
                    //绘制分辨率文字背景
                    //靠近屏幕上方和右边缘调整背景绘图位置,避免超出屏幕范围
                    if (this.rect.Y < 16)
                    {
                        if(this.rect.X + 70 > this.Width - 71)
                            gs.FillRectangle(backBrush,this.rect.X - 71,this.rect.Y,70,15);
                        else
                            gs.FillRectangle(backBrush, this.rect.X, this.rect.Y, 70, 15);
                    }
                    else
                    {
                        if(this.rect.X > this.Width - 71)
                            gs.FillRectangle(backBrush,this.rect.X - 71,this.rect.Y - 16,70,15);
                        else
                            
                            gs.FillRectangle(backBrush, this.rect.X, this.rect.Y - 16, 70, 15);
                    }
                }
                //定义绘制文字字体
                using (Font drawFont = new Font("Arial", 9))
                {
                    //定义分辨率文字画刷
                    using (SolidBrush drawBrush = new SolidBrush(Color.White))
                    {
                        //获取分辨率文字
                        string ratio = this.rect.Width.ToString() + " x " + rect.Height.ToString();
                        //绘制分辨率文字
                        if (this.rect.Y < 16)
                        {
                            if(this.rect.X > this.Width - 71)
                                gs.DrawString(ratio,drawFont,drawBrush,new Point (this.rect.X - 71,this.rect.Y));
                            else
                                gs.DrawString(ratio, drawFont, drawBrush, new Point(this.rect.X, this.rect.Y));
                        }
                        else
                        {
                            if(this.rect.X > this.Width - 71)
                                gs.DrawString(ratio,drawFont,drawBrush,new Point(this.rect.X - 71,this.rect.Y - 16));
                            else
                                gs.DrawString(ratio, drawFont, drawBrush, new Point(this.rect.X, this.rect.Y - 16));
                        }
                    }
                }
            } 
        }
--------------------编程问答--------------------

//放开鼠标左键,设置状态
        private void Catch_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                //不允许绘制和调整
                this.isDraw = false;
                this.isAdjust = false;
            }
        }
        //鼠标双击复制截图到剪贴板并存储
        private void Catch_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && isCatched == true)
            {
                //新建矩形大小的图片,并作为画板
                Bitmap bmp = new Bitmap(rect.Width, rect.Height);
                using (Graphics gs = Graphics.FromImage(bmp))
                {
                    //从原始截屏图片originBmp上截取指定的矩形部分rect到图片画板bmp的指定部分,单位为像素。
                        gs.DrawImage(this.originBmp, new Rectangle(0, 0, this.rect.Width, this.rect.Height), this.rect, GraphicsUnit.Pixel);
                }
                //复制到剪贴板
                Clipboard.SetImage(bmp);
                SaveFile(bmp);
  
            }
        }
        //储存图片
        private void SaveFile(Bitmap bmp)
        {
            //用当前时间作为文件名
            string time = DateTime.Now.ToString();
            //去除时间中的非法字符
            string filename = null;
            foreach(char symbol in time)
            {
                if(symbol != '/' && symbol != ':' && symbol != ' ')
                    filename += symbol;
            }
            saveFileDialog1.FileName = "截图" + filename;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)

            {
                //存储为jpeg或者png格式
                switch (saveFileDialog1.FilterIndex)
                {    
                    case 0:
                        bmp.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Png);
                        break;
                    case 1:
                        bmp.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                        break;
                    default:
                        bmp.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                        break;
                }
            }
            //退出截图
            this.Close();
        }
        //窗口关闭时设置主窗口的截图状态标记
        private void Catch_Closing(object sender, EventArgs e)
        {
            SetICSEvent(false);
        }
        //判定并记录鼠标与矩形框的位置关系,改变鼠标形状,并记录下矩形框上的一个标记点,
        //用作计算调节矩形框时矩形框的位置及大小     
        private void CursorLocation ()
        {
            int mouseX = Control.MousePosition.X;
            int mouseY = Control.MousePosition.Y;
            //鼠标在矩形内
            if (mouseX > rect.Left + 2 && mouseX < rect.Right - 2 && mouseY > rect.Top + 2 && mouseY < rect.Bottom - 2)
            { 
                Cursor.Current = Cursors.SizeAll;
                if (this.isAdjust == true)
                {
                    this.mouseLocation = MouseLocation.InRectangle;
                    this.fixedPoint = new Point(this.rect.Left, this.rect.Top);
                }
            }
            //鼠标在矩形外
            else if(mouseX <rect.Left - 2 || mouseX > rect.Right + 2 || mouseY < rect.Top - 2 || mouseY > rect.Bottom + 2)
            {
                Cursor.Current = Cursors.Default;
                this.mouseLocation = MouseLocation.OutOfRectangle;
            }
            //鼠标在矩形上
            else
            {
                //鼠标在矩形的左边宽以及顶点上
                if(mouseX > rect.Left - 3 && mouseX < rect.Left + 3)
                {
                    if (mouseY > rect.Top - 3 && mouseY < rect.Top + 3)
                    {
                        Cursor.Current = Cursors.SizeNWSE;
                        if (this.isAdjust == true)
                        {
                            this.mouseLocation = MouseLocation.LeftUpPoint;
                            this.fixedPoint = new Point(this.rect.Right, this.rect.Bottom);
                        }
                    }
                    else if (mouseY > rect.Bottom - 3 && mouseY < rect.Bottom + 3)
                    {
                        Cursor.Current = Cursors.SizeNESW;
                        if (this.isAdjust == true)
                        {
                            this.mouseLocation = MouseLocation.LeftDownPoint;
                            this.fixedPoint = new Point(this.rect.Right, this.rect.Top);
                        }
                    }
                    else
                    {
                        Cursor.Current = Cursors.SizeWE;
                        if (this.isAdjust == true)
                        {
                            this.mouseLocation = MouseLocation.LeftLine;
                            this.fixedPoint = new Point(this.rect.Right, this.rect.Top);
                        }
                    }
                }
                //鼠标在矩形的右边宽以及顶点上
                else if(mouseX > rect.Right - 3 && mouseX < rect.Right + 3)
                {
                    if (mouseY == rect.Top)
                    {
                        Cursor.Current = Cursors.SizeNESW;
                        if (this.isAdjust == true)
                        {
                            this.mouseLocation = MouseLocation.RightUpPoint;
                            this.fixedPoint = new Point(this.rect.Left, this.rect.Bottom);
                        }
                    }
                    else if (mouseY > rect.Bottom - 3 && mouseY < rect.Bottom  + 3)
                    {
                        Cursor.Current = Cursors.SizeNWSE;
                        if (this.isAdjust == true)
                        {
                            this.mouseLocation = MouseLocation.RightDownPoint;
                            this.fixedPoint = new Point(this.rect.Left, this.rect.Top);
                        }
                    }
                    else
                    {
                        Cursor.Current = Cursors.SizeWE;
                        if (this.isAdjust == true)
                        {
                            this.mouseLocation = MouseLocation.RightLine;
                            this.fixedPoint = new Point(this.rect.Left, this.rect.Top);
                        }
                        
                    }
                }
                //鼠标在矩形的长上
                else
                {
                    if (mouseY > rect.Top - 3 && mouseY < rect.Top + 3)
                    {
                        Cursor.Current = Cursors.SizeNS;
                        if (this.isAdjust == true)
                        {
                            this.mouseLocation = MouseLocation.UpLine;
                            this.fixedPoint = new Point(this.rect.Left, this.rect.Bottom);
                        }
                    }
                    else
                    {
                        Cursor.Current = Cursors.SizeNS;
                        if (this.isAdjust == true)
                        {
                            this.mouseLocation = MouseLocation.DownLine;
                            this.fixedPoint = new Point(this.rect.Left, this.rect.Top);
                        }
                    }
                }
            }
        }
        //按下ESC键退出截图
        private void Catch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == 27)
            {
                    this.Close();
            }
        }

    }
}

        
--------------------编程问答--------------------

            支持一下,不过希望你能突出重点,而不是什么代码都往上贴。

整理出核心代码,你的收获以及和大家分享的经验恐怕更好。 --------------------编程问答--------------------
引用 4 楼  的回复:
支持一下,不过希望你能突出重点,而不是什么代码都往上贴。

整理出核心代码,你的收获以及和大家分享的经验恐怕更好。


再加一句 上代码的时候最好用上这个东西 不然代码多了看都懒得看 而且缩进也没有
--------------------编程问答-------------------- 代码可读性很差,你需要在一个团队里去提高自己 --------------------编程问答-------------------- 写的很好,就是代码太长了。代码最好分类、什么是事件、什么是方法。归整一下 --------------------编程问答-------------------- 屋顶上的女孩

--------------------编程问答--------------------
引用 4 楼  的回复:
支持一下,不过希望你能突出重点,而不是什么代码都往上贴。

整理出核心代码,你的收获以及和大家分享的经验恐怕更好。
 楼主插入源代码好了一点
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,