0

0

C# GDI+编程(一)

高洛峰

高洛峰

发布时间:2016-12-17 10:20:02

|

1396人浏览过

|

来源于php中文网

原创

虽然是c++的,但总有一些相通的地方。

窗口刷新的时候,会产生Paint事件,那么我们给这个事件添加一个处理函数。然后在这个函数里画图。就能保证所画的图不被刷新掉,

它可以总是显示。Paint事件对应的委托是:public delegate void PaintEventHandler(object sender, PaintEventArgs e);

先来个最简单的绘制,在窗口上画一根线。(创建WindowsForms应用程序)

   public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

          //添加Paint事件处理函数
            this.Paint += formPaint;
        }
        private void formPaint(Object sender, PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            //画笔,绿色,2像素宽
            Pen pen=new Pen(Color.FromArgb(0,255,0),2);
            //画一根线,两点是0,0和100,100
            graphics.DrawLine(pen,new Point(0,0),new Point(100,100));
        }
    }

像绘制直线,矩形,圆形,还有图片,都可以通过Graphics类来完成。

示例2:一个填充矩形

 Graphics graphics = e.Graphics;
 //蓝色画刷
 SolidBrush brush = new SolidBrush(Color.FromArgb(0, 0, 255));
  //一个矩形
 Rectangle rect = new Rectangle(0, 0, 100, 100);
 //填充一个矩形
 graphics.FillRectangle(brush, rect);

示例3:画一张png图片(用PNG是因为可以显示透明的图片,GIF图片也有这个作用)

        private void formPaint(Object sender, PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            //加载图片
            Image img=Image.FromFile("d:\\Image\\win.png");
            //图片显示起始位置
            Point strPoint=new Point(50,50);
            //不限制大小绘制
            graphics.DrawImage(img, strPoint);
            //缩小图片绘制,限制在一个矩形内
            Rectangle rect=new Rectangle(50,50,100,100);
            graphics.DrawImage(img, rect);
        }

用DrawString显示文字

DrawString在Grahpics类里有好几个重载,有的可以让字符串在一个矩形内显示,有的可以使用特定的显示格式。这里就不做详细介绍了。

只讲比较常用的。

看例子吧,处理键盘输入字符事件,在窗口显示输入的字符。如下:

    public partial class Form1 : Form
    {
        public static String strText = "";
        public Form1()
        {
            InitializeComponent();
            this.Paint += formPaint;
            this.KeyPress += formKeyPress;
          
        }
        private void formPaint(Object sender, PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            //创建画刷
            SolidBrush brush=new SolidBrush(Color.FromArgb(0,255,0));
            //创建字体
            Font font=new Font("宋体",20f);
            //显示字符串,在一个矩形内
            graphics.DrawString(strText, font, brush, this.ClientRectangle);
         
        }
        private void formKeyPress(object sender, KeyPressEventArgs e)
        {
            strText += e.KeyChar;
            //刷新整个窗口
            this.Invalidate();
        }
    }

还有graphics.DrawString(strText, font, brush, new Point(100, 100));显示方式,这个只是指定了文字显示的起始位置。

关于显示格式看下例:

 //显示字符串,在一个矩形内
 StringFormat strFormat = new StringFormat(StringFormatFlags.DirectionRightToLeft);
 graphics.DrawString(strText, font, brush, this.ClientRectangle,strFormat);

StringFormatFlags是一个枚举类型,自己一个一个试吧,看看每个枚举成员表示什么样的格式。

接下来,我们来看一下。Form类中默认处理事件的方法,和你的添加的事件处理方法,这两者有什么关系。

一个示例:处理鼠标左键事件

   public partial class Form1 : Form
    {
        private Color prBackColor;
        public Form1()
        {
            InitializeComponent();
            //窗口默认的背景颜色
            prBackColor = this.BackColor;
            //添加事件处理
            this.MouseDown += formMouseDown;
            this.MouseUp += formMouseUp;
        }
        //鼠标键按下事件处理方法
        private void formMouseDown(object sender, MouseEventArgs e)
        {
            //如果是鼠标右键按下
            if (e.Button == MouseButtons.Right)
            {
                Form1 form1 = (Form1)sender;
                //改变背景颜色
                form1.BackColor = Color.FromArgb(0, 255, 0);
            }
        }
        //鼠标键弹起(松开)事件处理方法
        private void formMouseUp(object sender, MouseEventArgs e)
        {
            if(e.Button==MouseButtons.Right)
            {
            Form1 form1 = (Form1)sender;
            form1.BackColor = prBackColor;
            }

        }

}

像鼠标键按下MouseDown和鼠标键松开,Form都有默认的事件处理方法,这些方法都是虚方法,你可以重写它们,比如重写

protected virtual void OnMouseDown(MouseEventArgs e);和protected virtual void OnMouseUp(MouseEventArgs e);

这样就可以不必添加事件处理方法,也能处理鼠标事件了,可以通过重写父类默认事件处理方法,来实现上面的例子。

而在查MSDN可以发现,像这些默认的事件处理方法,调用都能引发其对应的事件。比如,我调用了OnMouseDown就能引发鼠标左键按下事件,其实也就是执行了我们添加的事件处理方法(委托)。而且我们还是多播委托的,因为我们是用"+="添加委托方法的。

这样的话,如果你重写了OnMouseDown一定要在里面调用基类的OnMouseDown方法,

不然我们添加的MouseDown方法就不会被执行(如果有)

那么知道了上面那些,我就来做一个实际例子吧。重写OnPaintBackground绘制背景的方法。

Ghostwriter
Ghostwriter

Replit推出的AI编程助手,一个强大的IDE,编译器和解释器。

下载

  public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //重写OnPaintBackground方法
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //禁止基类处理,我们自己来绘制背景
            //base.OnPaintBackground(e);
            //透明背景画刷
            SolidBrush brush=new SolidBrush(Color.Transparent);
            //填充整个窗口
            e.Graphics.FillRectangle(brush,this.ClientRectangle);
            //再画一个圆圈
            Pen pen = new Pen(Color.FromArgb(0, 255, 0),3);
            e.Graphics.DrawEllipse(pen, this.ClientRectangle);
        }
    }

TextureBursh图片画刷

可以用图片来填充一个形状,如矩形,圆形。图片不够大则平铺显示。

示例:

   private void formPaint(Object sender, PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            //创建图片画刷
            Rectangle rect = new Rectangle(10, 10, 70, 70);
            TextureBrush brush = new TextureBrush(Image.FromFile("d:\\Image\\345.jpg"),rect);
            graphics.FillEllipse(brush, 0, 0, 200, 200);
        }

构造函数最后一个参数,rect表示要用图片的哪部分进行填充,10,10表示图片起始位置(左上角),70,70表示宽度和高度,注意不能超出图片原有范围。整张图片填充的话,则不需要指定rect。构造函数里填一个参数就行了。

LinearGradientBursh线性渐变画刷(这个类存在于System.Drawing.Drawing2D命名空间里)

LinearGradientBursh类有一个构造函数重载,它有四个参数,是两个点,和两种颜色。

这四个参数指定了起始点的颜色,和结束点的颜色。还有位置。

看下例:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Paint += formPaint;

        }
        private void formPaint(Object sender, PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            LinearGradientBrush lineBrush = new LinearGradientBrush(new Point(0, 0), new Point(50, 0),
                                            Color.FromArgb(255, 255, 255), Color.FromArgb(0, 0, 0));
            //填充整个窗口
            graphics.FillRectangle(lineBrush,this.ClientRectangle);
        }
    }

起始点是0,0 结束点是0,50的效果图。从白色到黑色的渐变颜色段。超过50的部分,又开始重新渐变。

就好比在使用PS的时候,渐变颜色是白到黑,然后拉一根线。起始点是0,0,结束点是0,50。

那么如果我用这个属性的渐变画刷在窗口随便画一个矩形是什么样的呢,看上面效果图就可以知道。

比如 graphics.FillRectangle(lineBrush, 0, 0, 100, 100);

这个矩形的画刷填充跟第一张效果的对应的矩形区域是一样的。

如果改变起始点和结束点的值,也可以看得出来。这其中是按着什么方式来填充的。

比如起始点改成0,0,结束点改变50,50。

 private void formPaint(Object sender, PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            LinearGradientBrush lineBrush = new LinearGradientBrush(new Point(0, 0), new Point(50, 50),
                                            Color.FromArgb(255, 255, 255), Color.FromArgb(0, 0, 0));
            //填充整个窗口
            graphics.FillRectangle(lineBrush, this.ClientRectangle);
            Pen pen = new Pen(Color.FromArgb(0, 255,0));
            graphics.DrawRectangle(pen, 0, 0, 50, 50);
        }

在里面绘制填充图形,就是按上面的规则来显示的。这个窗口并没有禁止掉最大化功能,可以改变窗口大小以便更进一步的观察。

多种颜色渐变

LinearGradientBrush类有个InterpolationColors属性成员可以指定多种颜色渐变,这个成员是一个ColorBlend类型,像之前的渐变,都只能限于两种颜色的渐变,使用了InterpolationColors后,就可以使用多种,如从红到绿的渐变,然后绿到蓝。

看示例:

   private void formPaint(Object sender, PaintEventArgs e)
        {
           //创建ColorBlend对象,指定多种颜色渐变信息
            ColorBlend color_blend=new ColorBlend();
            //指定几种颜色
            color_blend.Colors=new Color[]{Color.Red,Color.Green,Color.Blue};
            //指定颜色的范围
            color_blend.Positions=new float[]{0/3f,2/3f,3/3f};
            Rectangle rect=new Rectangle(0,0,200,100);
            //创建渐变画刷
            LinearGradientBrush brush=
                new LinearGradientBrush(new Point(0,0),new Point(200,0),Color.White,Color.White);
        
            brush.InterpolationColors=color_blend;
            e.Graphics.FillRectangle(brush,rect);
        }

color_blend.Colors数组是指定有多少颜色渐变,比如上面就是红绿蓝,那么渐变应该是这样的,从红到绿渐变,然后从绿到蓝渐变。

color_blend.Positions指定颜色的范围,如把那上面那个矩形宽度看作整体1的话,那么红到绿渐变,是从0/3f至2/3f完成的,也就是在这个

范围内完成了红到绿的渐变,那么绿到蓝渐变的范围就是2/3f至3/3f。

如果要各占一半的话,那就是color_blend.Positions=new float[]{0/2f,1/2f,2/2f};

更多C# GDI+编程(一)相关文章请关注PHP中文网!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

178

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

35

2026.01.28

ao3中文版官网地址大全
ao3中文版官网地址大全

AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

79

2026.01.28

php怎么写接口教程
php怎么写接口教程

本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

2

2026.01.28

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

4

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

8

2026.01.28

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

24

2026.01.27

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

122

2026.01.26

edge浏览器怎样设置主页 edge浏览器自定义设置教程
edge浏览器怎样设置主页 edge浏览器自定义设置教程

在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

72

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 7.8万人学习

C 教程
C 教程

共75课时 | 4.3万人学习

C++教程
C++教程

共115课时 | 14.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号