思路:
截取屏幕图片。
获取要截取的范围,即左上角,右下角坐标
填充到picturebox中。
笔触功能,荧光笔,矩形,橡皮擦,复制,保存功能
涉及的知识点:
menustrip:为窗体提供菜单系统。以toolstripmenuitem为菜单子选项
toolstrip:为 windows 工具栏对象提供容器。以toolstripbutton【表示包含文本和图像的可选】为工具栏子元素
picturebox:表示用于显示图像的 windows 图片框控件。不过本文对此空间进行了重写
screen:可用于获取工作屏幕区域
graphics:封装一个 gdi+ 绘图图面。此类不能被继承。此类的copyfromscreen方法用于获取屏幕图像
鼠标事件:包括mousedown,mousemove,mouseup事件,通过mouseeventargs中的location获取鼠标的位置。
clipboard: 提供将数据置于系统剪贴板中以及从中检索数据的方法。此类不能被继承。
cursor:设置鼠标的显示的光标的样式。
onpaint:重绘事件,当控件刷新时响应此事件。
效果图如下【主要实现了截图,保存,复制,画矩形,笔触,荧光笔,橡皮擦等功能】:
保存后图片如下:
-------------------------------------------------------------------------------------------------------------------------------
核心代码如下:
截取屏幕图像:
1 public bitmap getscreen() 2 { 3 //获取整个屏幕图像,不包括任务栏 4 rectangle screenarea = screen.getworkingarea(this); 5 bitmap bmp = new bitmap(screenarea.width, screenarea.height); 6 using (graphics g = graphics.fromimage(bmp)) 7 { 8 g.copyfromscreen(0, 0, 0, 0, new size(screenarea.width,screenarea.height)); 9 }10 return bmp;11 }
view code
绘制图形功能:
1 #region 绘制功能 2 3 protected override void onpaint(painteventargs pe) 4 { 5 base.onpaint(pe); 6 graphics g = pe.graphics; 7 drawhistory(g); 8 //绘制当前线 9 if (startdraw && this.curline.pointlist != null && this.curline.pointlist.count > 0) 10 { 11 drawline(g,this.curline); 12 } 13 if (startdraw && this.currect.start != null && this.currect.end != null && this.currect.start != this.currect.end) { 14 drawrectangle(g, this.currect); 15 } 16 } 17 18 public void drawhistory(graphics g) { 19 //绘制线历史记录 20 if (linehistory != null) 21 { 22 foreach (hline lh in linehistory) 23 { 24 if (lh.pointlist.count > 10) 25 { 26 drawline(g, lh); 27 } 28 } 29 } 30 //绘制矩形历史记录 31 if (recthistory != null) 32 { 33 foreach (hrectangle lh in recthistory) 34 { 35 if (lh.start!=null&& lh.end!=null && lh.start!=lh.end) 36 { 37 drawrectangle(g, lh); 38 } 39 } 40 } 41 } 42 43 /// <summary> 44 /// 绘制线 45 /// </summary> 46 /// <param name="g"></param> 47 /// <param name="line"></param> 48 private void drawline(graphics g,hline line) { 49 g.smoothingmode = smoothingmode.antialias; 50 using (pen p = new pen(line.linecolor, line.linewidth)) 51 { 52 //设置起止点线帽 53 p.startcap = linecap.round; 54 p.endcap = linecap.round; 55 56 //设置连续两段的联接样式 57 p.linejoin = linejoin.round; 58 g.drawcurve(p, line.pointlist.toarray()); //画平滑曲线 59 } 60 } 61 62 /// <summary> 63 /// 绘制矩形 64 /// </summary> 65 /// <param name="g"></param> 66 /// <param name="rect"></param> 67 private void drawrectangle(graphics g, hrectangle rect) 68 { 69 g.smoothingmode = smoothingmode.antialias; 70 using (pen p = new pen(rect.linecolor, rect.linewidth)) 71 { 72 //设置起止点线帽 73 p.startcap = linecap.round; 74 p.endcap = linecap.round; 75 76 //设置连续两段的联接样式 77 p.linejoin = linejoin.round; 78 g.drawrectangle(p, rect.start.x, rect.start.y, rect.end.x - rect.start.x, rect.end.y - rect.start.y); //画平滑曲线 79 } 80 } 81 82 public void earser(point p0) 83 { 84 for (int i = linehistory.count - 1; i >= 0; i--) 85 { 86 hline line = linehistory[i]; 87 bool flag = false; 88 foreach (point p1 in line.pointlist) 89 { 90 double distance = getdistance(p0, p1); 91 if (math.abs(distance) < 6) 92 { 93 //需要删除 94 flag = true; 95 break; 96 } 97 98 } 99 if (flag)100 {101 linehistory.removeat(i);102 }103 }104 //擦除矩形105 for (int i = recthistory.count - 1; i >= 0; i--)106 {107 hrectangle rect = recthistory[i];108 109 if (p0.x>rect.start.x && p0.x<rect.end.x && p0.y > rect.start.y && p0.y < rect.end.y) {110 111 recthistory.removeat(i);112 }113 }114 }115 116 /// <summary>117 /// 获取两点之间的距离118 /// </summary>119 /// <param name="p0"></param>120 /// <param name="p1"></param>121 /// <returns></returns>122 private double getdistance(point p0, point p1) {123 return math.sqrt(math.pow((p0.x - p1.x), 2) + math.pow((p0.y - p1.y), 2));124 }125 126 #endregion
view code
以上就是c# 实现截图功能的操作实例的详细内容。
