首页 后端开发 C#.Net教程 C# GDI+编程(一)

C# GDI+编程(一)

Dec 17, 2016 am 10:20 AM

虽然是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绘制背景的方法。

  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中文网!


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

char在C语言中如何处理特殊字符 char在C语言中如何处理特殊字符 Apr 03, 2025 pm 03:18 PM

C语言中通过转义序列处理特殊字符,如:\n表示换行符。\t表示制表符。使用转义序列或字符常量表示特殊字符,如char c = '\n'。注意,反斜杠需要转义两次。不同平台和编译器可能有不同的转义序列,请查阅文档。

char在C语言字符串中的作用是什么 char在C语言字符串中的作用是什么 Apr 03, 2025 pm 03:15 PM

在 C 语言中,char 类型在字符串中用于:1. 存储单个字符;2. 使用数组表示字符串并以 null 终止符结束;3. 通过字符串操作函数进行操作;4. 从键盘读取或输出字符串。

char与wchar_t在C语言中的区别 char与wchar_t在C语言中的区别 Apr 03, 2025 pm 03:09 PM

在 C 语言中,char 和 wchar_t 的主要区别在于字符编码:char 使用 ASCII 或扩展 ASCII,wchar_t 使用 Unicode;char 占用 1-2 个字节,wchar_t 占用 2-4 个字节;char 适用于英语文本,wchar_t 适用于多语言文本;char 广泛支持,wchar_t 依赖于编译器和操作系统是否支持 Unicode;char 的字符范围受限,wchar_t 的字符范围更大,并使用专门的函数进行算术运算。

C语言各种符号的使用方法 C语言各种符号的使用方法 Apr 03, 2025 pm 04:48 PM

C 语言中符号的使用方法涵盖算术、赋值、条件、逻辑、位运算符等。算术运算符用于基本数学运算,赋值运算符用于赋值和加减乘除赋值,条件运算符用于根据条件执行不同操作,逻辑运算符用于逻辑操作,位运算符用于位级操作,特殊常量用于表示空指针、文件结束标记和非数字值。

c#多线程和异步的区别 c#多线程和异步的区别 Apr 03, 2025 pm 02:57 PM

多线程和异步的区别在于,多线程同时执行多个线程,而异步在不阻塞当前线程的情况下执行操作。多线程用于计算密集型任务,而异步用于用户交互操作。多线程的优势是提高计算性能,异步的优势是不阻塞 UI 线程。选择多线程还是异步取决于任务性质:计算密集型任务使用多线程,与外部资源交互且需要保持 UI 响应的任务使用异步。

char在C语言中如何进行类型转换 char在C语言中如何进行类型转换 Apr 03, 2025 pm 03:21 PM

在 C 语言中,char 类型转换可以通过:强制类型转换:使用强制类型转换符将一种类型的数据直接转换为另一种类型。自动类型转换:当一种类型的数据可以容纳另一种类型的值时,编译器自动进行转换。

C语言 sum 的作用是什么? C语言 sum 的作用是什么? Apr 03, 2025 pm 02:21 PM

C语言中没有内置求和函数,需自行编写。可通过遍历数组并累加元素实现求和:循环版本:使用for循环和数组长度计算求和。指针版本:使用指针指向数组元素,通过自增指针遍历高效求和。动态分配数组版本:动态分配数组并自行管理内存,确保释放已分配内存以防止内存泄漏。

char数组在C语言中如何使用 char数组在C语言中如何使用 Apr 03, 2025 pm 03:24 PM

char 数组在 C 语言中存储字符序列,声明为 char array_name[size]。访问元素通过下标运算符,元素以空终止符 '\0' 结尾,用于表示字符串终点。C 语言提供多种字符串操作函数,如 strlen()、strcpy()、strcat() 和 strcmp()。

See all articles