使用GDI+

GDI+是.Net Framework中的绘图API,我们通过调用GDI+可以指示.Net Framework底层具体调用特定的设备驱动程序,来在屏幕上绘制图像。这篇笔记我们介绍如何使用GDI+。

GDI+中的核心类

在WinForms应用程序中,GDI+包含以下几个核心类:

GraphicsGraphics是GDI+图形绘制的核心,它提供了一系列方法用于绘制线条、矩形、圆形、图像等。

Pen:该类表示用于绘制线条的对象,它可以定义线条的颜色、宽度、样式等属性。

Brush:该类用于填充图形,我们可以使用单一颜色或纹理等填充。

Font:该类用于定义绘制文本时的字体样式和大小。

Color:该类表示颜色,它可以创建常见的颜色(如红色、绿色、蓝色等),也可以使用RGB参数自定义颜色。

Image:该类封装了图像,它可以加载不同格式的图片,具体格式包括BMP、JPEG、JPG2000、PNG、GIF、TIFF、ICO、WMF、EMF。

这些类都位于System.Drawing命名空间。

坐标系统

GDI+使用的是屏幕坐标系,原点和坐标轴方向与大多数GUI框架类似。

原点:GDI+的坐标系原点位于图形区域的左上角。原点的坐标默认是(0, 0)

坐标轴:X轴是水平轴,向右为正方向;Y轴是垂直轴,向下为正方向。

使用GDI+绘图

这里我们介绍GDI+绘图的用法,不过我们不会逐一介绍所有API,具体参考微软官方文档即可。

绘制图形线框

为了简单起见,我们直接在主窗体的Paint事件中编写绘制代码,Paint事件会在窗口每次需要重绘时回调。下面代码我们在窗体的(0, 0)(100, 100)两个坐标之间绘制了一条黑色的直线。

using System.Drawing;
using System.Windows.Forms;

namespace Demo01
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            using (Graphics graphics = this.CreateGraphics())
            using (Pen pen = new Pen(Color.Black))
            {
                graphics.DrawLine(pen, 0, 0, 100, 100);
            }
        }
    }
}

每次用完GraphicsPen后,我们应该调用其Dispose()方法释放资源,这里我们就直接使用using语法自动释放了。代码中,我们调用了graphics.DrawLine()方法,它用于绘制直线。

填充图形颜色

GDI+中,填充颜色使用Brush类。下面代码我们绘制了一个黑色的圆形。

using System.Drawing;
using System.Windows.Forms;

namespace Demo01
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            using (Graphics graphics = this.CreateGraphics())
            using (Brush solidBrush = new SolidBrush(Color.Black))
            {
                graphics.FillEllipse(solidBrush, 0, 0, 100, 100);
            }
        }
    }
}

代码中,我们调用了graphics.FillEllipse()方法,它的参数是Brush对象和椭圆的绘制参数。

绘制文字

绘制文字需要使用BrushFont类,后者用于设置绘制的字体,下面是一个例子。

using System.Drawing;
using System.Windows.Forms;

namespace Demo01
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            using (Graphics graphics = this.CreateGraphics())
            using (Brush solidBrush = new SolidBrush(Color.Black))
            using (Font font = new Font("隶书", 20))
            {
                graphics.DrawString("Hello, Winform!", font, solidBrush, 100, 100);
            }
        }
    }
}

绘制图片

绘制图片需要使用Image类,Winform程序中图片可以添加为资源,我们在Visual Studio中右键点击项目->属性,转到资源标签页,在这里即可添加资源图片。

using System.Drawing;
using System.Windows.Forms;

namespace Demo01
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            using (Graphics graphics = this.CreateGraphics())
            {
                graphics.DrawImage(Properties.Resources.Image1, 0, 0);
            }
        }
    }
}

代码中,我们通过Properties.Resources.Image1取出资源,它是一个Image对象,我们调用graphics.DrawImage()方法并指定坐标即可绘制它。

坐标系变换

如果我们需要对绘制的图像进行一些位置或旋转操作,直接计算新的坐标可能不太方便,GDI+支持直接对绘图的坐标系进行平移、旋转和缩放,下面例子我们对坐标系设置X、Y轴上都放大2倍。

using System.Drawing;
using System.Windows.Forms;

namespace Demo01
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            using (Graphics graphics = this.CreateGraphics())
            using (Pen pen = new Pen(Color.Black))
            {
                graphics.DrawRectangle(pen, 0, 0, 100, 50);
                graphics.DrawEllipse(pen, 0, 0, 100, 50);

                graphics.ScaleTransform(2, 2);

                graphics.DrawRectangle(pen, 0, 0, 100, 50);
                graphics.DrawEllipse(pen, 0, 0, 100, 50);
            }
        }
    }
}

效果如下图所示。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap