实验二:用winform实现画图

实验目的

构造属于你的专属画图程序,可参考系统自带的绘图板


环境

  1. 操作系统: Windows 10 X64
  2. IDE: visual studio 2017
  3. 语言:C#

界面布局及控件使用

  • 整个页面 :Panel
  • 文件菜单 :MenuStrip
  • 主页,查看菜单 :TabControl
  • 绘图板 :PictureBox
  • 控制绘图板大小 :PictureBox
  • 工具、图形按钮 :Button
  • 粗细 :Label
  • 实线虚线 :Label
  • 填充按钮 :Label
  • 功能模块分区 :Panel
  • 功能模块分区的名字 :Label
  • 颜色板 :自定义控件名为 userControl1
  • 左下角的实时坐标 :StatusStrip
  • 按钮的文本提示 : ToolTip

界面展示


Point1–画布画板

画布相当于一张纸,我们使用两张纸,一张originalimage用于保留最终绘图并贴在画板上;一张interimage用于保存中间绘图痕迹。
比如画一个矩形

  1. 画图前先将中间画布初始化为原始画布(去掉绘图痕迹)
  2. 将矩形画在在中间画布
  3. 在鼠标释放时将中间画布复制给原始画布
  4. 将原始画布贴到画板上

Point2–颜色板的实现

新建及使用
  1. 新建项目->选择visual C# ->Windows 桌面 ->Windows窗体控件库
  2. 完成编辑后,在项目文件中找到 bin文件下的后缀为.dll的文件拖拽进工具箱即可。
完成效果:

使用的控件:
  • 颜色按钮:Button
  • 编辑颜色按钮:ColorDialog
  • 颜色1,2面板:Panel
功能实现:
  1. 选择颜色,判断改变颜色1还是颜色2

      private void button_Click(object sender, EventArgs e)
    {Button currentButton = (Button)sender;currentLabel.BackColor = currentButton.BackColor; if(currentLabel==label1){label1.BackColor = currentButton.BackColor;color1 = currentButton.BackColor;}else{label7.BackColor = currentButton.BackColor;color2 = currentButton.BackColor;}
    }
    
  2. 颜色1颜色2切换
    方法:设置一个currentlabel指向当前颜色label

       private void color1_Click(object sender, EventArgs e){currentLabel = label1;label3.BackColor = Color.PowderBlue;label4.BackColor = Color.Transparent;}private void color2_Click(object sender, EventArgs e){currentLabel = label7;label4.BackColor = Color.PowderBlue;label3.BackColor = Color.Transparent;}
    
  3. colordialog 调用颜色对话框,并将颜色添加到可用按钮中
    重点:colorDialog1.ShowDialog()

     private void makecolor_Click(object sender, EventArgs e){if (colorDialog1.ShowDialog() == DialogResult.OK){Color mycolor = colorDialog1.Color;for (int i = 0; i < haveUse; i++){if (allButton[i].BackColor == mycolor)//与第i个重复,则从第i+1个到num-1个都向前移动一格{for (int k = i; k < NUM - 1; k++){allButton[k].BackColor = allButton[k + 1].BackColor;}haveUse--;break;}}if (haveUse == NUM)//已经满了,前移一格{for (int i = 0; i < NUM - 1; i++){allButton[i] = allButton[i + 1];}allButton[NUM - 1].BackColor = mycolor;haveUse++;}else//还没满{allButton[haveUse].BackColor = mycolor;allButton[haveUse].Enabled = true;haveUse++;}}}
    

Point3–绘制图形

重点:绘制图形的函数

        //使用Graphics对象实现switch (type){case "nonerh"://无填充菱形{PointF[] pointFs = { new PointF(leftX + width / 2, leftY), new PointF(leftX, leftY + height / 2), new PointF(leftX + width / 2, leftY + height), new PointF(leftX + width, leftY + height / 2) };interGraphics.DrawPolygon(mypen, pointFs);break;}case "solidrh"://纯色菱形{PointF[] pointFs = { new PointF(leftX + width / 2, leftY), new PointF(leftX, leftY + height / 2), new PointF(leftX + width / 2, leftY + height), new PointF(leftX + width, leftY + height / 2) };interGraphics.FillPolygon(new SolidBrush(backcolor), pointFs);interGraphics.DrawPolygon(mypen, pointFs);break;}case "hatchrh"://圆点填充{PointF[] pointFs = { new PointF(leftX + width / 2, leftY), new PointF(leftX, leftY + height / 2), new PointF(leftX + width / 2, leftY + height), new PointF(leftX + width, leftY + height / 2) };interGraphics.FillPolygon(new HatchBrush(HatchStyle.LargeConfetti, backcolor, Color.White), pointFs);interGraphics.DrawPolygon(mypen, pointFs);break;}case "nonetriangle"://无填充等腰三角形{PointF[] pointfs = { new PointF((startPoint.X + currentPoint.X) / 2, startPoint.Y), new PointF(startPoint.X, currentPoint.Y), currentPoint };interGraphics.DrawPolygon(mypen, pointfs);break;}case "solidtriangle"://纯色填充等腰三角形{PointF[] pointfs = { new PointF((startPoint.X + currentPoint.X) / 2, startPoint.Y), new PointF(startPoint.X, currentPoint.Y), currentPoint };interGraphics.FillPolygon(new SolidBrush(backcolor), pointfs);interGraphics.DrawPolygon(mypen, pointfs);break;}case "hatchtriangle"://圆点填充等腰三角形{PointF[] pointfs = { new PointF((startPoint.X + currentPoint.X) / 2, startPoint.Y), new PointF(startPoint.X, currentPoint.Y), currentPoint };interGraphics.FillPolygon(new HatchBrush(HatchStyle.LargeConfetti, backcolor, Color.White), pointfs);interGraphics.DrawPolygon(mypen, pointfs);break;}case "nonetriangle2"://无填充直角三角形{PointF[] pointfs = { startPoint, new PointF(startPoint.X, currentPoint.Y), currentPoint };interGraphics.DrawPolygon(mypen, pointfs);break;}case "solidtriangle2"://纯色填充直角三角形{PointF[] pointfs = { startPoint, new PointF(startPoint.X, currentPoint.Y), currentPoint };interGraphics.FillPolygon(new SolidBrush(backcolor), pointfs);interGraphics.DrawPolygon(mypen, pointfs);break;}case "hatchtriangle2"://圆点填充直角三角形{PointF[] pointfs = {startPoint, new PointF(startPoint.X, currentPoint.Y), currentPoint };interGraphics.FillPolygon(new HatchBrush(HatchStyle.LargeConfetti, backcolor, Color.White), pointfs);interGraphics.DrawPolygon(mypen, pointfs);break;}case "noneline"://直线interGraphics.DrawLine(mypen, startPoint, currentPoint);break;case "nonerectangle"://无填充矩形interGraphics.DrawRectangle(mypen, leftX, leftY, width, height);break;case "noneellipse"://无填充椭圆{               interGraphics.DrawEllipse(mypen, leftX, leftY, width, height);break;}case "nonearc"://弧线{                   if (width != 0 && height != 0)interGraphics.DrawArc(mypen, leftX, leftY, width, height, 0, 180);break;}case "nonepie"://无填充饼形{if (width != 0 && height != 0)interGraphics.DrawPie(mypen, leftX, leftY, width, height, 0, 180);break;}case "solidrectangle"://纯色填充矩形{interGraphics.FillRectangle(new SolidBrush(backcolor), leftX, leftY, width, height);interGraphics.DrawRectangle(mypen, leftX, leftY, width, height);break;}case "solidellipse"://纯色填充椭圆{interGraphics.FillEllipse(new SolidBrush(backcolor), leftX, leftY, width, height);interGraphics.DrawEllipse(mypen, leftX, leftY, width, height);break;}case "solidpie"://纯色填充饼形{if (width != 0 && height != 0){interGraphics.FillPie(new SolidBrush(backcolor), leftX, leftY, width, height, 0, 180);interGraphics.DrawPie(mypen, leftX, leftY, width, height, 0, 180);}break;}case "hatchrectangle"://圆点填充矩形{interGraphics.FillRectangle(new HatchBrush(HatchStyle.LargeConfetti,backcolor,Color.White), leftX, leftY, width, height);interGraphics.DrawRectangle(mypen, leftX, leftY, width, height);break;}case "hatchellipse"://圆点填充椭圆{interGraphics.FillEllipse(new HatchBrush(HatchStyle.LargeConfetti,backcolor,Color.White), leftX, leftY, width, height);interGraphics.DrawEllipse(mypen, leftX, leftY, width, height);break;}case "hatchpie"://圆点填充饼形{if (width != 0 && height != 0){interGraphics.FillPie(new HatchBrush(HatchStyle.LargeConfetti, backcolor,Color.White), leftX, leftY, width, height, 0, 180);interGraphics.DrawPie(mypen, leftX, leftY, width, height, 0, 180);}break;}}

Point4–铅笔

方法:使用DrawLine画线方法 从startpoint 到 currentpoint

    public void Pencile(MouseEventArgs e)//铅笔{PointF currentPoint = new PointF(e.X-10, e.Y+8);Graphics interGraphics = Graphics.FromImage(interImg);interGraphics.DrawLine(mypen, startPoint,currentPoint);originalImg = (Image)interImg.Clone();targetGraphics.DrawImage(originalImg,0,0);startPoint = currentPoint;}

Point5–橡皮

方法:相当于用纯色矩形覆盖,用DrwaRectangle方法

      public void Eraser(MouseEventArgs e)//橡皮擦{PointF currentPoint = new PointF(e.X, e.Y);Graphics interGraphics = Graphics.FromImage(interImg);interGraphics.FillRectangle(new SolidBrush(backcolor), startPoint.X-5,startPoint.Y-5,16,10);originalImg = (Image)interImg.Clone();targetGraphics.DrawImage(originalImg, 0, 0);startPoint = currentPoint;}

Point6–粗细、线条、填充

粗细:设置pen的Width属性

线条:设置pen的DashStyle属性。实现为Solid,虚线为Dot

填充:无填充:使用pen画;纯色填充:先用SolidBrush笔刷画,再用pen画上边;圆点填充:先用HatchBrush笔刷(设置属性HatchStyle.LargeConfetti)画,再用pen画上边


Point7–文本框

使用TextBox,点击绘图板,当绘图板里没有文本框时,显示文本框;有文本框时,移除文本框并将文本框的文字绘到绘图板上
重点:

  1. 动态添加控件:panel10.Controls.Add(mytb);(panel0为父容器)

  2. 动态删除控件:panel10.Controls.Remove(control);

  3. 绘制文字:interGraphics.DrawString(str, font, brush,pointF);
    font为字体样式,brush为字体填充笔刷,pointF为字体在父容器中的相对位置。

         if (drawtype == "text"){if (Extentionclass.FindControl(panel10, "mytb") == null)//第一次按下{TextBox mytb = new TextBox();mytb.Name = "mytb";mytb.Location = new Point(e.X, e.Y+pictureBox1.Location.Y);//位置mytb.BorderStyle = BorderStyle.FixedSingle;panel10.Controls.Add(mytb);//     panel10.Controls.SetChildIndex(mytb, 100);mytb.BringToFront();}else{Control control = Extentionclass.FindControl(panel10, "mytb");string str =control.Text;Font font = new Font("宋体", 9);Brush brush = new SolidBrush(userControl11.Color1);PointF pointF = new PointF(control.Location.X, control.Location.Y - pictureBox1.Location.Y);panel10.Controls.Remove(control);Graphics interGraphics = Graphics.FromImage(tool.InterImage);interGraphics.DrawString(str, font, brush,pointF);graphics.DrawImage(tool.InterImage, 0, 0);}}
    

Point8–新建文件、保存文件

新建文件之前要判断是否保存文件
用到的方法:

  1. 消息提示框:MessageBox.Show(“是否要保存文件”, “系统提示”, MessageBoxButtons.YesNoCancel);

  2. 保存、另存为、新建文件:如下代码

  3. 新建时要初始化绘画板

       private void 新建ToolStripMenuItem_Click(object sender, EventArgs e){//是否保存DialogResult dialogResult = MessageBox.Show("是否要保存文件", "系统提示", MessageBoxButtons.YesNoCancel);if (dialogResult==DialogResult.Yes)//选择先保存{if (sFilename != null)//可以直接保存{if (MessageBox.Show("是否要保存文件?", "系统提示", MessageBoxButtons.YesNo) == DialogResult.Yes)//选择yes保存{tool.OriginalImage.Save(sFilename);}}else{SaveFileDialog saveFile = new SaveFileDialog();//            saveFile.FileName = "";saveFile.Filter = "JPG|*.jpg;*.jpeg;*.jpe;*.jfif|GIF|*.gif|PNG|*.png|TIF|*.tif;*.tiff|ICO|*.ico|所有文件|*.*";if (saveFile.ShowDialog() == DialogResult.OK)//文件夹显示成功{sFilename = saveFile.FileName;tool.OriginalImage.Save(sFilename);}}}else if(dialogResult==DialogResult.Cancel)//取消则什么都不做直接返回{return;}////新建Bitmap  bmap= new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);Graphics g = Graphics.FromImage(bmap);g.FillRectangle(new SolidBrush(Color.White), 0, 0, bmap.Width, bmap.Height);g.Dispose();tool.targetGraphics.DrawImage(bmap,0,0);tool.OriginalImage = bmap;bmap.Dispose();}
    

Point9–打开文件

打开之前要提示是否保存文件

        OpenFileDialog openFile = new OpenFileDialog();openFile.FileName = "";openFile.Filter = "JPG|*.jpg;*.jpeg;*.jpe;*.jfif|GIF|*.gif|PNG|*.png|TIF|*.tif;*.tiff|ICO|*.ico|所有文件|*.*";if (openFile.ShowDialog() == DialogResult.OK)//文件夹显示ok(成功){if(openFile.FileName!=""){//插入是否保存代码Bitmap bitmap = new Bitmap(openFile.FileName);//从指定的文件初始化bitmappictureBox1.Size = bitmap.Size;//调整绘图区大小为图片大小pictureBox3.Location = new Point(pictureBox1.Width, pictureBox1.Height + pictureBox1.Location.Y);//改变那个小角角的大小Bitmap bm = new Bitmap(pictureBox1.Width, pictureBox1.Height);Graphics g = Graphics.FromImage(bm);g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));g.DrawImage(bitmap, 0, 0);g.Dispose();tool.targetGraphics = pictureBox1.CreateGraphics();tool.targetGraphics.DrawImage(bm, 0, 0);tool.OriginalImage = bm;bitmap.Dispose();bm.Dispose();sFilename = openFile.FileName;openFile.Dispose();}}}

Point10–清除

方法:绘制一个和画板一样大小的白色矩形,注意要更新原始画布和中间画布

    private void 清除ToolStripMenuItem_Click(object sender, EventArgs e){Bitmap newpic = new Bitmap(pictureBox1.Width,  pictureBox1.Height);Graphics g = Graphics.FromImage(newpic);g.FillRectangle(new SolidBrush(Color.White), 0, 0,pictureBox1.Width, pictureBox1.Height);g.Dispose();g = pictureBox1.CreateGraphics();g.DrawImage(newpic, 0, 0);g.Dispose();tool.OriginalImage = newpic;}

Point11–退出

点击Form右上角的关闭角标时调用Form1_FormClosing方法
点击菜单项的关闭选项时用this.close()
关闭前要提示是否保存


Point12–改变画板大小

改变画板大小通过画板右下角的一个小pictruebox(pb)实现。移动pb改变pb的位置,根据pb的相对于父容器的位置(即location)及画板的location得到画板的大小,改变画板大小后要改变初始画布和中间画布的大小,并将画布重新贴在画板上才能显示图案。

      private bool isResize = false;private void pictureBox3_MouseDown(object sender, MouseEventArgs e){isResize = true;}private void pictureBox3_MouseMove(object sender, MouseEventArgs e){if (isResize){pictureBox3.Location = new Point(pictureBox3.Location.X + e.X, pictureBox3.Location.Y + e.Y);}}private void pictureBox3_MouseUp(object sender, MouseEventArgs e){isResize = false;pictureBox1.Size = new Size(pictureBox3.Location.X-pictureBox1.Location.X, pictureBox3.Location.Y-pictureBox1.Location.Y);//改变大小tool.targetGraphics = pictureBox1.CreateGraphics();//再次设置Bitmap newBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);Graphics tempGraphic = Graphics.FromImage(newBitmap);tempGraphic.FillRectangle(new SolidBrush(Color.White), 0, 0, pictureBox1.Width, pictureBox1.Height);//创建一张新的临时画纸tempGraphic.DrawImage(tool.OriginalImage, 0, 0);//将original画在上面tempGraphic.Dispose();//   graphics = pictureBox1.CreateGraphics();//tempGraphic =pictureBox1.CreateGraphics();//tempGraphic.DrawImage(newBitmap, 0, 0);//tempGraphic.Dispose();//  tool.targetGraphics.DrawImage(newBitmap, 0, 0);//--为什么不能重绘绘图板tool.OriginalImage = newBitmap;newBitmap.Dispose();}

知识点1——关于按钮图片的方法

右击解决方案里的项目->进入属性->找到左侧的资源->将图像导入其中->找到按钮的image属性导入图片

知识点2——设置坐标图标

进入该项目的项目文件夹->进入bin文件夹->进入debug文件夹->在debug文件夹中创建一个文件夹存放.ico或者.cur图片
相应代码如下:

pictureBox1.Cursor = new Cursor(Application.StartupPath + @"\img\pen.ico");

知识点3——绘图板重绘

在改变绘图板的大小,或者绘图板被覆盖之后要调用重绘绘图板方法才能显示图像

      private void pictureBox1_Paint(object sender, PaintEventArgs e){Graphics g = e.Graphics;g.DrawImage(tool.OriginalImage, 0, 0);}

C# Winform画图相关推荐

  1. winform 画图的放大和缩小_画错图纸被判3年,罚10万!画图真的需要严谨

    加入我们报团取暖外协订单|技术交流加入机械微信群→加入机械是一门严谨的实践性很强的学科,就图纸而言,那更是不能出错,一处有错,实际应用就会谬之千里.你能看出这个图的错误吗?机械图纸的种类机械类图纸有很 ...

  2. C#winform画图简易制作

    制作一个画图十分简单,只需要用到一个picturebox(画图通用)控件,一个button控件(开始,停止画画,这个十分重要,可以防止勿画) 注意,在这里需要用到MouseMove,MouseDown ...

  3. winform 画图的放大和缩小_CAD绘图区域突然不能放大或缩小了怎么办?【AutoCAD教程】...

    点击蓝色字关注我哟 ☀每天推送CAD软件安装及下载.CAD工具应用.CAD技巧.CAD教程.CAD素材.CAD疑难问题解答等文章 ☀想认识志同道合的朋友一起学习CAD?请加入我们的QQ群 369845 ...

  4. 简单的c#winform画图工具

    1首先创建一个form窗体 然后拖入pictureBox作为画板 2创建两个button按钮 一个为"开始画画 " 一个"保存" 对于画板的创建 首先 我们得声 ...

  5. AI应用开发实战(转)

    AI应用开发实战 - 从零开始配置环境 与本篇配套的视频教程请访问:https://www.bilibili.com/video/av24421492/ 建议和反馈,请发送到 https://gith ...

  6. AI应用开发实战 - 手写识别应用入门

    AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...

  7. AI应用开发实战系列之三:手写识别应用入门

    AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...

  8. C#在透明窗体WinForm上面画图(电子尺小工具的实现)

    前几天要做一个微信调一调的外挂,里面用到了尺子测量距离,然后就自己下载了一个电子尺,最近要升级我的跳一跳外挂,然后就准备自己做一个电子尺,嵌入到我的外挂里面,在嵌入到我的外挂之前,我自己做了一个完整版 ...

  9. Winform仿Win10画图工具

    Winform仿Win10画图工具: 源码区: using System; using System.Collections.Generic; using System.ComponentModel; ...

最新文章

  1. 搭建windows下filezilla FTP服务器
  2. 非静态方法可以调用静态变量吗
  3. 【STM32】输入捕获实验代码详解
  4. C++尽可能使用const
  5. ComboBox自动补全小技巧
  6. python爬虫网络出错怎么办_Python爬虫常见问题
  7. Linux 设备驱动开发 —— Tasklets 机制浅析
  8. Linux Ubuntu 安装 anaconda3和 Pycharm 社区版本
  9. 车票?工作?对象?Python 教你优雅解决年关三大难题!
  10. 多线程编程-之并发编程:同步容器
  11. css 的z-index研究
  12. git clone提示鉴权失败
  13. Excel如何用IF函数进行数据筛选
  14. 振动试验设备的选择和使用
  15. CKEditor富文本编辑器使用
  16. C语言 6习题13 编一程序,将两个字符串连接起来,不要用strcat函数。
  17. 深度学习 目标分类 思路
  18. 如何预防电脑辐射(转自j2medev)
  19. 卡内基梅隆计算机硕士录取案例,学子喜获计算机牛校卡内基梅隆录取
  20. Word2003画箭头锦囊 斜线箭头、双箭头、折线箭头

热门文章

  1. html边框显示长短调整,CSS之border边框长度控制
  2. HCIA网工数通Datacom之网工初级
  3. SceneTree类
  4. Transformer Architectures and Pre-training Strategies for Fast and Accurate Multi-sentence Scoring
  5. 论文阅读——Deep 3D Portrait from a Single Image(CVPR2020)
  6. 蚂蚁调度AntJob-分布式任务调度系统
  7. 05-SA8155 QNX I2C框架及代码分析
  8. Vue基础-vue指令
  9. 用海伦公式计算三角形的周长与面积
  10. 【iOS】内存五大分区