C# -VS2019通过重写pictureBox实现简单的桌面截图功能

前言

通过创建客制化组件(继承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/ 
本文版权归作者和博客园共有,欢迎转载【点赞】,转载请保留此段声明,且在文章页面明显位置给出原文连接,谢谢。

猜你喜欢

转载自www.cnblogs.com/jeremywucnblog/p/11976490.html