【C#】图形图像编程
实验目标和要求:
- 掌握C#图形绘制基本概念;
- 掌握C#字体处理;
- 能进行C#图形图像综合设计。
运行效果如下所示:

1.功能说明与核心代码
使用panel为画板,完成以下设计内容:
- 使用pen绘制基础图形;
- 使用LinearGradientBrush实现渐变色字体;
- 使用GraphicsPath实现艺术字,部分核心代码如下所示;
GraphicsPath gp = new GraphicsPath(FillMode.Winding);gp.AddString("字体轮廓",new FontFamily("方正舒体"),(int)FontStyle.Regular,80,new PointF(10, 20),new StringFormat());Brush brush = XXXXXXXXXXXXXXXXXXXXXX;XXX.DrawPath(Pens.Green, gp);XXX.FillPath(brush, gp);
实现:
1.在vs中开一个c#的窗体应用:
2 .在设计界面中拉取两个button,一个textbox(用于输出自己想输出的内容(艺术字))以及一个panel(输出在panel上显示)

3.代码
(1)button1:
private void button1_Click(object sender, EventArgs e)
{drawBasicShapes = true;drawArtText = false;DrawBasicShapes();panel1.Invalidate(); // 触发重绘
}
(2)button2:
private void button2_Click(object sender, EventArgs e){drawBasicShapes = false;drawArtText = true;DrawArtText();panel1.Invalidate(); // 触发重绘}
(3)button1调用的函数DrawBasicShapes():
private void DrawBasicShapes()
{// 使用 Pen 绘制基础图形Pen blackPen = new Pen(Color.Black, 3);drawingGraphics.DrawRectangle(blackPen, 10, 70, 100, 50);drawingGraphics.DrawEllipse(blackPen, 10, 70, 100, 50);// 使用 LinearGradientBrush 实现渐变色字体Font font = new Font("Arial", 24);LinearGradientBrush gradientBrush = new LinearGradientBrush(new Rectangle(10, 20, 100, 50),Color.Blue,Color.Red,45);drawingGraphics.DrawString("直接拿捏", font, gradientBrush, new PointF(10, 150));
}
(4)button2调用的函数 DrawArtText():
private void DrawArtText()
{string text = textBox1.Text;using (Font font = new Font("方正舒体", 40, FontStyle.Regular))using (GraphicsPath gp = new GraphicsPath(FillMode.Winding))using (SolidBrush brush = new SolidBrush(Color.AliceBlue)) // 使用 SolidBrush 填充艺术字 using (Pen pen = new Pen(Color.Green, 2)) // 使用 Pen 绘制艺术字的轮廓 {gp.AddString(text,font.FontFamily,(int)font.Style,font.Size,new PointF(80, 30), // 设置艺术字的起始位置 StringFormat.GenericDefault);drawingGraphics.DrawPath(pen, gp); // 绘制艺术字的轮廓 drawingGraphics.FillPath(brush, gp); // 填充艺术字 }
}
(5)panel:
private void panel1_Paint(object sender, PaintEventArgs e)
{// 将 Bitmap 绘制到 Panel 上e.Graphics.DrawImage(drawingBitmap, 0, 0);
}
4.代码细节补充(完整代码)
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Windows.Forms;
using System;namespace 图形图像编程
{public partial class Form1 : Form{// 标志位private bool drawBasicShapes = false;private bool drawArtText = false;// Bitmap 对象,用于保存绘制的图像private Bitmap drawingBitmap;private Graphics drawingGraphics;// 构造函数public Form1(){InitializeComponent();// 初始化 Bitmap 和 Graphics 对象drawingBitmap = new Bitmap(panel1.Width, panel1.Height);drawingGraphics = Graphics.FromImage(drawingBitmap);// 绑定按钮点击事件button1.Click += new EventHandler(this.button1_Click);button2.Click += new EventHandler(this.button2_Click);panel1.Paint += new PaintEventHandler(this.panel1_Paint);}// 绘制基础图形按钮点击事件处理private void button1_Click(object sender, EventArgs e){drawBasicShapes = true;drawArtText = false;DrawBasicShapes();panel1.Invalidate(); // 触发重绘}// 添加艺术字按钮点击事件处理private void button2_Click(object sender, EventArgs e){drawBasicShapes = false;drawArtText = true;DrawArtText();panel1.Invalidate(); // 触发重绘}// 绘制基础图形的方法private void DrawBasicShapes(){// 使用 Pen 绘制基础图形Pen blackPen = new Pen(Color.Black, 3);drawingGraphics.DrawRectangle(blackPen, 10, 70, 100, 50);drawingGraphics.DrawEllipse(blackPen, 10, 70, 100, 50);// 使用 LinearGradientBrush 实现渐变色字体Font font = new Font("Arial", 24);LinearGradientBrush gradientBrush = new LinearGradientBrush(new Rectangle(10, 20, 100, 50),Color.Blue,Color.Red,45);drawingGraphics.DrawString("直接拿捏", font, gradientBrush, new PointF(10, 150));}// 绘制艺术字的方法private void DrawArtText(){string text = textBox1.Text;using (Font font = new Font("方正舒体", 40, FontStyle.Regular))using (GraphicsPath gp = new GraphicsPath(FillMode.Winding))using (SolidBrush brush = new SolidBrush(Color.AliceBlue)) // 使用 SolidBrush 填充艺术字 using (Pen pen = new Pen(Color.Green, 2)) // 使用 Pen 绘制艺术字的轮廓 {gp.AddString(text,font.FontFamily,(int)font.Style,font.Size,new PointF(80, 30), // 设置艺术字的起始位置 StringFormat.GenericDefault);drawingGraphics.DrawPath(pen, gp); // 绘制艺术字的轮廓 drawingGraphics.FillPath(brush, gp); // 填充艺术字 }}// Panel的Paint事件处理private void panel1_Paint(object sender, PaintEventArgs e){// 将 Bitmap 绘制到 Panel 上e.Graphics.DrawImage(drawingBitmap, 0, 0);}}
}
运行结果:


小结:
1.实现细节
· 创建项目和设计窗体:
- 新建一个Windows Forms应用程序项目。
- 在窗体上添加一个Panel控件和两个Button控件以及textbox。
- 设置Button控件的文本为“绘制基础图形”和“添加艺术字”。
· 初始化绘图资源:
- 在窗体构造函数中,初始化一个Bitmap对象和一个Graphics对象。
- 将Bitmap对象的大小设置为Panel控件的大小。
- 使用Graphics.FromImage方法从Bitmap对象创建一个Graphics对象,用于绘图。
· 实现按钮点击事件处理函数:
- 在第一个按钮的点击事件处理函数中,调用绘制基础图形的方法。
- 在第二个按钮的点击事件处理函数中,调用绘制艺术文字的方法。
- 在每个事件处理函数中,调用panel1.Invalidate方法,触发重绘。
· 实现绘图方法:
- 在绘制基础图形的方法中,使用Pen对象绘制矩形和椭圆,使用LinearGradientBrush对象绘制渐变色文字。
- 在绘制艺术文字的方法中,使用GraphicsPath对象创建艺术文字的路径,并使用SolidBrush对象填充文字。
· 处理Panel的Paint事件:
- 在Paint事件处理函数中,使用Graphics.DrawImage方法将Bitmap对象绘制到Panel控件上。
2.小结
本次实验通过使用GDI+进行图形和文字的绘制,成功实现了一个可以动态更新绘图内容的Windows窗体应用程序。关键点在于使用Bitmap对象作为绘图表面,从而保留之前的绘图内容。这种方法适用于需要动态更新和保留图形内容的应用场景
难点分析
(1)Bitmap与Graphics的初始化和使用:
初始化Bitmap和Graphics对象并确保它们的大小与Panel一致,这样才能确保绘制内容能够正确显示在Panel上。
在Panel的Paint事件中使用Graphics.DrawImage方法将Bitmap绘制到Panel上,以实现内容的保留和更新。
(2)不同绘图操作的协调:
实现多个绘图方法并确保它们能够在同一个Bitmap对象上操作,不会互相覆盖或清除之前的绘图内容。
(3)处理界面刷新:
通过调用panel1.Invalidate方法触发重绘,并在Paint事件中绘制Bitmap对象,这样可以确保每次绘制新内容时,之前的内容不会被清除。
相关文章:
【C#】图形图像编程
实验目标和要求: 掌握C#图形绘制基本概念;掌握C#字体处理;能进行C#图形图像综合设计。 运行效果如下所示: 1.功能说明与核心代码 使用panel为画板,完成以下设计内容: 使用pen绘制基础图形;使…...
埃特巴什码加解密小程序
埃特巴什码加解密小程序 这几天在看CTF相关的课程,涉及到古典密码学和近代密码学还有现代密码学。 简单替换密码 Atbash Cipher 埃特巴什码(Atbash Cipher)其实可以视为下面要介绍的简单替换密码的特例,它使用字母表中的最后 一个字母代表第一个字母…...
Golang笔记:使用serial包进行串口通讯
文章目录 目的使用入门总结 目的 串口是非常常用的一种电脑与设备交互的接口。这篇文章将介绍golang中相关功能的使用。 本文使用的包为 :go.bug.st/serial https://pkg.go.dev/go.bug.st/serial https://github.com/bugst/go-serial 另外还有一些常见的包如&…...
EasyExcel 导出批注信息
1. 批注信息 package com.xxx.demo;import lombok.Getter;/*** This class represents the comment information associated with a specific cell in an Excel sheet.* The columnIndex field specifies the column number of the cell, and the comment field stores the te…...
HttpServletRequest・getContentLeng・getContentType区别
getContentLength(): 获取客户端发送到服务器的HTTP请求主体内容的字节数(长度) 如果请求没有正文内容(如GET),或者请求头中没有包含Content-Length字段,则该方法返回 -1 getContentType()&am…...
Matlab|【防骗帖】考虑时空相关性的风电功率预测误差建模与分析
目录 1 主要内容 2 部分程序 3 下载链接 1 主要内容 这个程序《考虑时空相关性的风电功率预测误差建模与分析》画的图片非常漂亮,和原文献基本一致,但是实际上内容并未实现出来,主要就是利用现有的风电预测的数据和结果做了相关的图&#…...
【Android面试八股文】说一说ListView卡顿的原因以及相对应的优化策略
文章目录 一、ListView卡顿的原因1.1 Item没有复用1.2 布局的层级过深1.3 数据绑定逻辑过多1.4 滑动时不必要的图片刷新1.5 频繁的notifyDataSetChanged二、优化策略2.1 使用 ViewHolder 进行视图复用2.2 优化布局结构2.3 优化数据绑定逻辑过多2.4 图片加载优化2.5 避免频繁调用…...
Kotlin 中的内联函数
1 inline 内联函数:消除 Lambda 带来的运行时开销。 举例来说: fun main() {val num1 100val num2 80val result num1AndNum2(num1, num2) { n1, n2 ->n1 n2} }fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int …...
KALI LINUX 开启ssh免登录服务及固定ip及
SSH以进行远程登录 在Kali Linux中启用SSH以进行远程登录,请按照以下步骤操作: 安装SSH服务:sudo apt update sudo apt install openssh-server 已安装可忽略 sudo systemctl start ssh 启动SSH服务 sudo systemctl enable ssh 确保SSH服务设置为开机启动: (可选)如…...
亮数据,一款新的低代码爬虫利器!
在当今数据驱动型时代,数据采集和分析能力算是个人和企业的核心竞争力。然而,手动采集数据耗时费力且效率低下,而且容易被网站封禁。 我之前使用过一个爬虫工具,亮数据(Bright Data) ,是一款低…...
配置OSPF认证(华为)
#交换设备 配置OSPF认证-基于华为路由器 OSPF(开放最短路径优先)是一种内部网关协议(IGP),用于在单一自治系统(AS)内决策路由。OSPF认证功能是路由器中的一项安全措施,它的主要用途…...
关于ip地址的网页无法访问navigator的gpu、媒体、蓝牙等设备的解决方法
在使用threejs的WebGPURenderer渲染器时,发现localhost以及127.0.0.1才能访问到navigator.gpu,直接使用ip会变成undefined,原因是为了用户的隐私安全,只能在安全的上下文中使用,非安全的上下文就会是undefined,安全上下…...
深入理解外观模式(Facade Pattern)及其实际应用
引言 在软件开发中,复杂的系统往往由多个子系统组成,这些子系统之间的交互可能非常复杂。外观模式(Facade Pattern)通过为这些子系统提供一个统一的接口,简化了它们的交互。本篇文章将详细介绍外观模式的概念、应用场…...
为什么永远不会有语言取代 C/C++?
每个 CPU 都带有一种称为 ISA(指令集架构)汇编的电路语言。ISA 程序集是一种硬件语言,由基本数据操作、数学计算和结构化编程(即 jmp)的操作组成。但是,为每个计算需求编写汇编代码无疑是耗时的,…...
Python 全栈体系【四阶】(六十一)
第五章 深度学习 十三、自然语言处理(NLP) 5. NLP应用 5.2 文本情感分析 目标:利用训练数据集,对模型训练,从而实现对中文评论语句情感分析。情绪分为正面、负面两种 数据集:中文关于酒店的评论&#…...
工控必备C#
微软的C# 语言? QT 熟了以后,Qt 更方便些 方法Signal Slot 感觉上一样 现在更推荐PyQt 来构建,底层还是Qt C 的那些库,Qt 的开源协议有点狗...
【设计模式之基于特性的动态路由映射模式】
在ASP.NET Core中,路由是核心功能之一,用于将HTTP请求映射到相应的控制器操作。虽然“路由驱动设计模式”是一个我刚杜撰出来的设计模式名称,但我们可以基于ASP.NET Core的路由特性,构建一种以路由为中心的设计模式。 以下是一个…...
GB 16807-2009 防火膨胀密封件
防火膨胀密封件是指在火灾时遇火或高温作用能够膨胀,且能辅助建筑构配件使之具有隔火、隔烟、隔热等防火密封性能的产品。 GB 16807-2009 防火膨胀密封件测试项目 测试要求 测试标准 外观 GB 16807 尺寸允许偏差 GB 16807 膨胀性能 GB 16807 产烟毒性 GB …...
从零开始做题:老照片中的密码
老照片中的密码 1.题目 1.1 给出图片如下 1.2 给出如下提示 这张老照片中的人使用的是莫尔斯电报机,莫尔斯电报机分为莫尔斯人工电报机和莫尔斯自动电报机(简称莫尔斯快机)。莫尔斯人工电报机是一种最简单的电报机,由三个部分组…...
考研数学|张宇和武忠祥,强化能不能同时跟?
可以说你跟武老师学明白了,120完全没问题!如果追求更高,宇哥的怀抱也想你敞开! 学长我21年一战数学83,总分没过线,22年二战143,逆袭上岸211!市面上的老师我基本都听过,最…...
提示词工程的应用解析
提示词工程全解析:从入门到精通,让AI精准读懂你的需求[TOC](提示词工程全解析:从入门到精通,让AI精准读懂你的需求)提示词工程全解析:从入门到精通,让AI精准读懂你的需求一、引言:为什么提示词工…...
电动汽车 Simulink 模型探索:从模块到实际应用
电动汽车模型的各模块simulink模型包括驾驶员模块,电机模块,控制器模块等,包含模块讲解文档在电动汽车的研发领域,通过 Simulink 构建模型是深入理解和优化车辆性能的关键一步。今天咱们就来唠唠电动汽车模型里几个重要的 Simulin…...
从仿真到实物:音频功率放大器PCB设计前的Proteus验证全流程
从仿真到实物:音频功率放大器PCB设计前的Proteus验证全流程 在硬件开发领域,音频功率放大器的设计往往需要经历多次迭代才能达到理想性能。传统开发流程中,工程师们常常需要反复制作PCB原型并进行实测,这不仅耗时耗力,…...
Qwen3模型快速部署教程:10分钟搞定GPU环境与首次调用
Qwen3模型快速部署教程:10分钟搞定GPU环境与首次调用 你是不是也对那些动辄几十GB、部署起来让人头大的大模型望而却步?觉得在自己的机器上跑起来一个像样的AI模型,是件门槛很高的事情? 今天,我就带你打破这个刻板印…...
突破Windows远程桌面限制:RDP Wrapper多用户并发实战指南
突破Windows远程桌面限制:RDP Wrapper多用户并发实战指南 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap 在远程办公与协作日益普及的今天,Windows远程桌面功能成为连接不同设备的重要桥梁。…...
python-flask-djangol框架的现代化动物园观光游览系统
目录技术选型与架构设计核心功能模块实现票务与游客管理智能化服务集成性能优化与测试部署与监控项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作技术选型与架构设计 采用Python的Flask或Django框架构建后端系统,具…...
dbg-macro配置完全指南:禁用宏、强制颜色输出与警告控制
dbg-macro配置完全指南:禁用宏、强制颜色输出与警告控制 【免费下载链接】dbg-macro A dbg(…) macro for C 项目地址: https://gitcode.com/gh_mirrors/db/dbg-macro dbg-macro是一款轻量级C调试宏工具,通过简单的dbg(...)语法即可实现变量值、类…...
深入解析串口通信:从RS232到RS485的工业应用实战
1. 串口通信的工业应用基础 第一次接触工业自动化项目时,我被现场密密麻麻的线缆搞得头晕眼花。直到老师傅指着角落里不起眼的两根双绞线说:"这条RS485总线控制着整条生产线的30台设备",我才意识到串口通信在工业领域的强大之处。 …...
串口转HID实战:CH9329芯片在无外网环境下的应用指南
CH9329芯片串口转HID实战:隔离环境下的设备控制方案 在工业控制、医疗设备和某些特殊应用场景中,经常需要在物理隔离的网络环境下实现设备控制。CH9329芯片作为一款串口转HID(人机接口设备)的专业芯片,为解决这类问题提…...
FPGA Multiboot翻车实录:从XDC配置到ICAPE2,我的W25Q128分区血泪史与避坑指南
FPGA Multiboot实战:从配置陷阱到Flash分区优化的全流程解析 第一次在量产产品中实现FPGA远程更新功能时,我盯着实验室里突然变砖的开发板,后背渗出一层冷汗。原本以为按照官方文档配置就能万无一失,没想到Multiboot这个看似简单的…...
