WInForm —— 自定义画板

项目模板:要实现在背景和无背景上完成画线,画直线、矩形、椭圆、并能随意调整字体的大小

 首先要定义绘制的类型

enum DrawMode
{None, // 没有选择绘制型Pen,  // 画笔 画直线Line,// 画直线Rectangle,// 画矩形Ellipse, // 画椭圆Rubber  // 橡皮擦
}

//如果要想绘制成图片可以使用picturebox作为载体,
//之前使用g.drawLine只是绘制到窗体,只是表面现象,并没有绘制成图片
//把绘制的效果形成一个图片使用drawImage方法

全局变量:

 Graphics g;  //绘制对象Graphics imgGra;// 把绘制出效果形成一个图片Color curColor = Color.Black;//设置画笔的颜色int penSize = 0;// 笔刷粗细string title; // 窗体的标题DrawMode curMode = DrawMode.None;//当前绘制的类型Image backImg;// 背景图片

设置下拉选项

 g = this.CreateGraphics();
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;toolStripComboBox1.SelectedIndex = 1; //设置下拉框默认值选择this.Text = "画板";

 选择背景

private void 选择文件ToolStripMenuItem_Click(object sender, EventArgs e)
{OpenFileDialog ofd = new OpenFileDialog();// 文本选择对话框ofd.Filter = "png图片|*.png|jpg图片|*.jpg"; //过滤文件类型ofd.Multiselect = false;//是否支持多选,if (ofd.ShowDialog() == DialogResult.OK){Image sourceImage =  Image.FromFile(ofd.FileName);// 加载对应路径的资源 把图片绘制的背景//this.ClientRectangle.Width窗体的宽度//this.ClientRectangle.Height窗体的高度backImg = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);//设置背景图片大小imgGra = Graphics.FromImage(backImg);// 把backImage作为绘制背景图// 把图片绘制到管理背景图的图像上imgGra//imgGra.DrawImage()g.Clear(Color.White); //把绘制区域以白色填充,目的先把之前的背景清空掉g.DrawImage(sourceImage, this.ClientRectangle);// 绘制图片,参数1是绘制的图片 参数2是绘制的区域this.Text = title + "\t" + ofd.FileName;}}

无背景

private void 无背景ToolStripMenuItem_Click(object sender, EventArgs e)
{// 设置无背景的背景图宽度和高度backImg = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height); //设置一张图片imgGra = Graphics.FromImage(backImg);// 把图片作为绘制的背景imgGra.Clear(Color.White); // 清空背景g.DrawImage(backImg, this.ClientRectangle);//绘制图片this.Text = title + "\t" + "未命名";}

点击画笔pen的事件

private void toolStripLabel2_Click(object sender, EventArgs e)
{//只是修改绘制的类型,真正绘制的时候在鼠标移动方法进行绘制curMode = DrawMode.Pen;
}

鼠标按下事件

 Point startPoint; // 起始点位置
 bool drawFlag;// 控制是否开始绘制的变量

private void Form1_MouseDown(object sender, MouseEventArgs e)
{if(e.Button == MouseButtons.Left){startPoint = e.Location;// 把点击点坐标赋值给起始点drawFlag = true;}}

 鼠标移动

private void Form1_MouseMove(object sender, MouseEventArgs e)
{if (drawFlag == false) return;switch (curMode) {case DrawMode.None: break;case DrawMode.Pen:// 粗细不要写定值 先写2g.DrawLine(new Pen(curColor, penSize), startPoint, e.Location);imgGra.DrawLine(new Pen(curColor, penSize), startPoint, e.Location);startPoint = e.Location;break;case DrawMode.Line:// 为了解决窗体最小化的时候出现 绘制的效果的消失的问题,//打开窗体重新调用绘制的方法,把backimage重新绘制到窗体上// 给窗体添加一个paint事件 把backimage重新绘制到窗体上Form1_Paint(null, null);g.DrawLine(new Pen(curColor, penSize), startPoint, e.Location);break;case DrawMode.Rectangle:Form1_Paint(null, null);g.DrawRectangle(new Pen(curColor, penSize), startPoint.X, startPoint.Y, e.Location.X - startPoint.X, e.Location.Y - startPoint.Y);break;case DrawMode.Ellipse:Form1_Paint(null, null);g.DrawEllipse(new Pen(curColor, penSize), startPoint.X, startPoint.Y, e.Location.X - startPoint.X, e.Location.Y - startPoint.Y);break;case DrawMode.Rubber:// 绘制一个白色的线就行g.DrawLine(new Pen(Color.White, 10), startPoint, e.Location);imgGra.DrawLine(new Pen(Color.White, 10), startPoint, e.Location);startPoint = e.Location;break;default: break;}}

鼠标松开

 private void Form1_MouseUp(object sender, MouseEventArgs e){drawFlag = false;switch (curMode){case DrawMode.None:break;case DrawMode.Pen:break;case DrawMode.Line:imgGra.DrawLine(new Pen(curColor, penSize), startPoint, e.Location);  break;case DrawMode.Rectangle:imgGra.DrawRectangle(new Pen(curColor, penSize), startPoint.X, startPoint.Y, e.Location.X - startPoint.X, e.Location.Y - startPoint.Y);break;case DrawMode.Ellipse:imgGra.DrawEllipse(new Pen(curColor, penSize), startPoint.X, startPoint.Y, e.Location.X - startPoint.X, e.Location.Y - startPoint.Y);break;case DrawMode.Rubber:break;default:break;}}

 修改笔刷的颜色

private void 颜色ToolStripMenuItem_Click(object sender, EventArgs e)
{//FontDialogColorDialog cd = new ColorDialog();if (cd.ShowDialog() == DialogResult.OK){curColor = cd.Color; //修改画笔颜色变量}}

修改笔刷大小的事件

private void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{penSize = Convert.ToInt16( toolStripComboBox1.Text);
}
修改绘制类型
private void toolStripLabel3_Click(object sender, EventArgs e)
{curMode = DrawMode.Line; //绘制直线
}
矩形
private void toolStripLabel4_Click(object sender, EventArgs e)
{//矩形curMode = DrawMode.Rectangle;
}
椭圆
private void toolStripLabel5_Click(object sender, EventArgs e)
{curMode = DrawMode.Ellipse;//椭圆
}

在改事件中重新绘制图片

private void Form1_Paint(object sender, PaintEventArgs e)
{if (backImg == null){return;}g.DrawImage(backImg, this.ClientRectangle);}
private void toolStripLabel6_Click(object sender, EventArgs e)
{curMode = DrawMode.Rubber;//
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/818347.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

9. Spring Boot 日志文件

本篇文章源码位置延续上个章节:SpringBoot_demo 本篇文章内容源码位于上述地址的com/chenshu/springboot_demo/logging包下 1. 日志的作用 发现和定位问题: 日志是程序的重要组成部分,它在系统、程序出现错误或异常时提供诊断和解决问题的线…

深度探索:Secure Hash Algorithm(SHA)全景解析

title: 深度探索:Secure Hash Algorithm(SHA)全景解析 date: 2024/4/15 18:33:17 updated: 2024/4/15 18:33:17 tags: SHA安全抗碰撞性算法版本实现细节性能优化发展历史应用案例 密码学中的哈希函数 一、哈希函数的定义 哈希函数是一种数…

外卖点餐APP开发需要哪些功能

uni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言:pythonjavanode.jsphp均支持 运行软件…

SCI 四区(JEI)投稿到录用过程中的经历和心得体会

计算机视觉领域中,包含目标检测、三维重建、语义分割、图像分类等分支。其中,目标检测分支最卷,你知道的,没有背景和资源,发一篇SCI属实不易。本篇博客详细介绍本人投稿到录用过程中的经历和心得。 目录 1. 硬件资源落…

Vitis HLS 学习笔记--优化循环启动间隔(II)

目录 1. 概述 2. 常规矩阵乘法 3. 数据依赖性和内存访问模式 4. 优化循环 5. 总结 1. 概述 Initiation Interval(II)定义为启动连续操作之间的时间间隔,以时钟周期为单位。低的II是高性能和高资源利用率的关键。 较高的II意味着在单位…

使用DockerCompose配置基于哨兵模式的redis主从架构集群

文章目录 一、注意事项(坑点!!!)二、配置Redis主从架构集群第一步:创建目录文件结构第二步:编写DockerCompose配置文件第三步:编写redis.conf第四步:启动redis主从集群 三…

CentOS如何使用Docker部署Plik服务并实现公网访问本地设备上传下载文件

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问,实现随时随地在任意设备上传或者…

C语言 递归

递归指的是在函数的定义中使用函数自身的方法。 举个例子: 从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?“从前有座山,山里有座庙,庙里有个老和尚&…

蓝桥杯-阿坤老师的魔方挑战

图示: 代码: #include <iostream> using namespace std; int main() {int N,i,j,row,col,sum,max0;cin>>N;int ar[N][N];for(i0;i<N;i){for(j0;j<N;j){cin>>ar[i][j];}//输入矩阵 }for(i0;i<N;i){row0;coli;sum0;//重新初始化while(row<N){if(c…

初识集合框架

前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x1f…

eclipse导入maven项目与配置使用本地仓库

前言 本人润国外了&#xff0c;发现不能用收费软件IDEA了&#xff0c;需要使用eclipse&#xff0c;这个免费。 但是早忘了怎么用了&#xff0c;在此总结下。 一、eclipse导入本地项目 1.选这个&#xff1a;open projects from file system… 2.找到项目文件夹&#xff0c;…

借力社交裂变,Xinstall助你实现用户快速增长

在数字化时代&#xff0c;社交裂变已成为品牌获取新用户、扩大影响力的关键手段。然而&#xff0c;如何有效利用社交裂变&#xff0c;实现用户快速增长&#xff0c;却是许多品牌面临的挑战。今天&#xff0c;我们将为大家介绍一个强大的社交裂变引擎——Xinstall&#xff0c;它…

Python中sort()函数、sorted()函数的用法深入讲解(具体实例:蓝桥杯数位排序)

前置知识&#xff1a; 可迭代对象的定义&#xff1a;可迭代对象是指可以被迭代或遍历的对象&#xff0c;即可以使用循环结构对其进行逐个访问的对象。 在Python中常见的可迭代对象有&#xff1a;列表(list)、元组&#xff08;tuple&#xff09;、字符串&#xff08;sting&…

基于SpringBoot+Vue实现的医院在线挂号系统(代码+万字文档)

系统介绍 基于SpringBootVue实现的医院在线挂号系统设计了三种角色&#xff0c;分别是管理员、医生、用户&#xff0c;每种角色对应不同的菜单 系统实现了个人信息管理、基础数据管理、论坛管理、用户管理、单页数据管理、医生管理及轮播图管理等功能模块&#xff0c;具体功能…

【大语言模型】基础:如何处理文章,向量化与BoW

词袋模型&#xff08;BoW&#xff09;是自然语言处理&#xff08;NLP&#xff09;和机器学习中一种简单而广泛使用的文本表示方法。它将文本文档转换为数值特征向量&#xff0c;使得可以对文本数据执行数学和统计操作。词袋模型将文本视为无序的单词集合&#xff08;或“袋”&a…

React 集成三方登录按钮样式的插件库

按钮不提供任何社交逻辑。 效果如下&#xff1a; 原地址&#xff1a;https://www.npmjs.com/package/react-social-login-buttons 时小记&#xff0c;终有成。

【C++成长记】C++入门 | 类和对象(中) |拷贝构造函数、赋值运算符重载、const成员函数、 取地址及const取地址操作符重载

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;C❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、拷贝构造函数 1、概念 2、特征 二、赋值运算符重载 1、运算符重载 2、赋值运算符重载 3、前置…

G2D图像处理硬件调用和测试-基于米尔-全志T113-i开发板

本篇测评由电子工程世界的优秀测评者“jf_99374259”提供。 本文将介绍基于米尔电子MYD-YT113i开发板的G2D图像处理硬件调用和测试。 MYC-YT113i核心板及开发板 真正的国产核心板&#xff0c;100%国产物料认证 国产T113-i处理器配备2*Cortex-A71.2GHz &#xff0c;RISC-V 外置…

SpringBoot启动流程分析之准备应用上下文refreshContext()

文章目录 源码入口1、准备刷新1.1、子类prepareRefresh()方法1.2 父类prepareRefresh&#xff08;&#xff09;方法 2、通知子类刷新内部bean工厂3、准备bean工厂4、允许上下文子类对bean工厂进行后置处理 源码入口 org.springframework.boot.SpringApplication#run(java.lang…

若依vue中关于字典的使用

文章目录 字典管理页面列表点击某个字典类型展示具体字典数据修改某一条字典数据 字典的应用一般用于select多选框中代码实现根据字典Dict的value获取Label&#xff0c;类似于通过key获得value 源码解析 字典管理页面 列表 点击某个字典类型展示具体字典数据 修改某一条字典数…