• C#


    前言

    通过创建客制化组件(继承pictureBox),新增属性和构造方法,实现屏幕截图时需要用到的功能点。再通过监控鼠标按下、移动和释放,来获取起始点区域。最后通过操作BMP图像,实现截图的新增、修改和保存功能。

    核心点

    • 组件的创建(重写)
    • 鼠标监控事件
    • BMP图像重绘

    核心代码

      1     /// <summary>
      2     /// 重写图片控件
      3     /// </summary>
      4     [Serializable]
      5     public partial class HexPictureBox : PictureBox
      6     {
      7         #region 属性和构造函数
      8 
      9         public HexPictureBox()
     10         {
     11             InitializeComponent();
     12         }
     13 
     14         private bool startDraw = false;
     15 
     16         public bool StartDraw
     17         {
     18             get { return startDraw; }
     19 
     20             set { startDraw = value; }
     21         }
     22 
     23         private List<HLine> lineHistory = new List<HLine>();
     24 
     25         public List<HLine> LineHistory
     26         {
     27             get { return lineHistory; }
     28 
     29             private set { lineHistory = value; }
     30         }
     31 
     32         private HLine curLine = new HLine() { LineColor = Color.White, LineWidth = 2, PointList = new List<Point>() };
     33 
     34         /// <summary>
     35         /// 当前绘制线
     36         /// </summary>
     37         public HLine CurLine
     38         {
     39             get { return curLine; }
     40 
     41             private set { curLine = value; }
     42         }
     43 
     44         private HRectangle curRect = new HRectangle() { LineColor = Color.White, LineWidth = 2, Start = new Point(0, 0), End = new Point(0, 0) };
     45 
     46         /// <summary>
     47         /// 当前需要绘制的矩形
     48         /// </summary>
     49         public HRectangle CurRect
     50         {
     51             get { return curRect; }
     52 
     53             set { curRect = value; }
     54         }
     55 
     56         private List<HRectangle> rectHistory = new List<HRectangle>();
     57 
     58         public List<HRectangle> RectHistory
     59         {
     60             get { return rectHistory; }
     61 
     62             private set { rectHistory = value; }
     63         }
     64 
     65         private DrawType drawTypes = DrawType.None;
     66 
     67         public DrawType DrawTypes
     68         {
     69             get { return drawTypes; }
     70 
     71             set { drawTypes = value; }
     72         }
     73 
     74         #endregion
     75 
     76         #region 绘制功能
     77 
     78         protected override void OnPaint(PaintEventArgs pe)
     79         {
     80             base.OnPaint(pe);
     81             Graphics g = pe.Graphics;
     82             DrawHistory(g);
     83             //绘制当前线
     84             if (startDraw && this.curLine.PointList != null && this.curLine.PointList.Count > 0)
     85             {
     86                 DrawLine(g, this.curLine);
     87             }
     88             if (startDraw && this.curRect.Start != null && this.curRect.End != null && this.curRect.Start != this.curRect.End)
     89             {
     90                 DrawRectangle(g, this.curRect);
     91             }
     92         }
     93 
     94         public void DrawHistory(Graphics g)
     95         {
     96             //绘制线历史记录
     97             if (LineHistory != null)
     98             {
     99                 foreach (HLine lh in LineHistory)
    100                 {
    101                     if (lh.PointList.Count > 10)
    102                     {
    103                         DrawLine(g, lh);
    104                     }
    105                 }
    106             }
    107             //绘制矩形历史记录
    108             if (RectHistory != null)
    109             {
    110                 foreach (HRectangle lh in RectHistory)
    111                 {
    112                     if (lh.Start != null && lh.End != null && lh.Start != lh.End)
    113                     {
    114                         DrawRectangle(g, lh);
    115                     }
    116                 }
    117             }
    118         }
    119 
    120         /// <summary>
    121         /// 绘制线
    122         /// </summary>
    123         /// <param name="g"></param>
    124         /// <param name="line"></param>
    125         private void DrawLine(Graphics g, HLine line)
    126         {
    127             g.SmoothingMode = SmoothingMode.AntiAlias;
    128             using (Pen p = new Pen(line.LineColor, line.LineWidth))
    129             {
    130                 //设置起止点线帽  
    131                 p.StartCap = LineCap.Round;
    132                 p.EndCap = LineCap.Round;
    133 
    134                 //设置连续两段的联接样式  
    135                 p.LineJoin = LineJoin.Round;
    136                 g.DrawCurve(p, line.PointList.ToArray()); //画平滑曲线  
    137             }
    138         }
    139 
    140         /// <summary>
    141         /// 绘制矩形
    142         /// </summary>
    143         /// <param name="g"></param>
    144         /// <param name="rect"></param>
    145         private void DrawRectangle(Graphics g, HRectangle rect)
    146         {
    147             g.SmoothingMode = SmoothingMode.AntiAlias;
    148             using (Pen p = new Pen(rect.LineColor, rect.LineWidth))
    149             {
    150                 //设置起止点线帽  
    151                 p.StartCap = LineCap.Round;
    152                 p.EndCap = LineCap.Round;
    153 
    154                 //设置连续两段的联接样式  
    155                 p.LineJoin = LineJoin.Round;
    156                 g.DrawRectangle(p, rect.Start.X, rect.Start.Y, rect.End.X - rect.Start.X, rect.End.Y - rect.Start.Y); //画平滑曲线  
    157             }
    158         }
    159 
    160         public void Earser(Point p0)
    161         {
    162             for (int i = lineHistory.Count - 1; i >= 0; i--)
    163             {
    164                 HLine line = lineHistory[i];
    165                 bool flag = false;
    166                 foreach (Point p1 in line.PointList)
    167                 {
    168                     double distance = GetDistance(p0, p1);
    169                     if (Math.Abs(distance) < 6)
    170                     {
    171                         //需要删除
    172                         flag = true;
    173                         break;
    174                     }
    175 
    176                 }
    177                 if (flag)
    178                 {
    179                     lineHistory.RemoveAt(i);
    180                 }
    181             }
    182             //擦除矩形
    183             for (int i = rectHistory.Count - 1; i >= 0; i--)
    184             {
    185                 HRectangle rect = rectHistory[i];
    186 
    187                 if (p0.X > rect.Start.X && p0.X < rect.End.X && p0.Y > rect.Start.Y && p0.Y < rect.End.Y)
    188                 {
    189 
    190                     rectHistory.RemoveAt(i);
    191                 }
    192             }
    193         }
    194 
    195         /// <summary>
    196         /// 获取两点之间的距离
    197         /// </summary>
    198         /// <param name="p0"></param>
    199         /// <param name="p1"></param>
    200         /// <returns></returns>
    201         private double GetDistance(Point p0, Point p1)
    202         {
    203             return Math.Sqrt(Math.Pow((p0.X - p1.X), 2) + Math.Pow((p0.Y - p1.Y), 2));
    204         }
    205 
    206         #endregion
    207 
    208         #region 鼠标事件响应
    209 
    210         /// <summary>
    211         /// 鼠标移动时设置点
    212         /// </summary>
    213         /// <param name="p"></param>
    214         public void SetPointAndRefresh(Point p)
    215         {
    216             if (this.drawTypes == DrawType.Line)
    217             {
    218                 this.curLine.PointList.Add(p);
    219             }
    220             if (this.drawTypes == DrawType.Rect)
    221             {
    222                 this.curRect.End = p;
    223             }
    224             this.Refresh();
    225 
    226         }
    227 
    228         public void OnMouseDown(Point p)
    229         {
    230             if (this.DrawTypes == DrawType.Line)
    231             {
    232                 this.CurLine.PointList.Clear();
    233                 this.CurLine.PointList.Add(p);
    234             }
    235             if (this.DrawTypes == DrawType.Rect)
    236             {
    237                 this.CurRect.Start = p;
    238             }
    239         }
    240 
    241         public void OnMouseUp(Point p)
    242         {
    243             if (this.DrawTypes == DrawType.Line)
    244             {
    245                 //右键起来时,停止绘图,并写入历史记录
    246                 Point[] pCopy = this.CurLine.PointList.ToArray();
    247                 List<Point> lstPoint = new List<Point>();
    248                 lstPoint.AddRange(pCopy);
    249                 this.LineHistory.Add(new HLine() { LineColor = this.CurLine.LineColor, LineWidth = this.CurLine.LineWidth, PointList = lstPoint });
    250                 this.CurLine.PointList.Clear();
    251             }
    252             if (this.DrawTypes == DrawType.Rect)
    253             {
    254                 this.RectHistory.Add(new HRectangle() { LineColor = this.CurRect.LineColor, LineWidth = this.CurRect.LineWidth, Start = this.CurRect.Start, End = this.CurRect.End });
    255                 this.CurRect.Start = new Point(0, 0);
    256                 this.CurRect.End = new Point(0, 0);
    257             }
    258             if (this.DrawTypes == DrawType.Earser)
    259             {
    260                 //如果是橡皮擦功能
    261                 this.Earser(p);
    262                 this.Refresh();
    263             }
    264         }
    265 
    266         #endregion
    267 
    268         #region 初始设置
    269 
    270         public void SetPen(Color c)
    271         {
    272             this.DrawTypes = DrawType.Line;
    273             this.CurLine.LineWidth = 2;
    274             this.CurLine.LineColor = c;
    275             //通过图片的句柄获取指针
    276             this.Cursor = new Cursor(global::ScreenShot.Properties.Resources.pen.GetHicon());
    277             this.StartDraw = true;
    278         }
    279 
    280         public void SetLightPen()
    281         {
    282             this.StartDraw = true;
    283             this.CurLine.LineWidth = 6;
    284             this.DrawTypes = DrawType.Line;
    285             this.Cursor = new Cursor(global::ScreenShot.Properties.Resources.lightpen.GetHicon());
    286             this.CurLine.LineColor = Color.FromArgb(100, Color.Yellow);
    287         }
    288 
    289         public void SetRectangle()
    290         {
    291             this.StartDraw = true;
    292             this.CurRect.LineWidth = 3;
    293             this.DrawTypes = DrawType.Rect;
    294             this.CurRect.LineColor = Color.Red;
    295             this.Cursor = Cursors.Cross;
    296         }
    297 
    298         public void SetEarser()
    299         {
    300             this.DrawTypes = DrawType.Earser;//橡皮檫
    301             this.Cursor = new Cursor(global::ScreenShot.Properties.Resources.easer1.GetHicon());
    302         }
    303 
    304         public void SetDefault()
    305         {
    306             this.Cursor = Cursors.Default;
    307             this.StartDraw = false;
    308         }
    309 
    310         #endregion
    311     }
    View Code

    实现效果

     

      作者:Jeremy.Wu
      出处:https://www.cnblogs.com/jeremywucnblog/
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    20162307 实验二实验报告
    20162307 第六周学习总结
    20162307 第5周学习总结
    20162306 2016-2017-2《程序设计与数据结构》第八周学习总结
    20162306 2016-2017-2《程序设计与数据结构》第七周学习总结
    第二次实验报告
    20162306 2016-2017-2《程序设计与数据结构》第六周学习总结
    20162306 2016-2017-2《程序设计与数据结构》第五周学习总结
    第一次实验报告
    20162306陈是奇 2016-2017-2《程序设计与数据结构》第四周学习总结
  • 原文地址:https://www.cnblogs.com/jeremywucnblog/p/11976490.html
Copyright © 2020-2023  润新知