前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2024年01月 GDI+绘图专题 DrawString

【愚公系列】2024年01月 GDI+绘图专题 DrawString

原创
作者头像
愚公搬代码
修改2024-01-03 08:26:20
2300
修改2024-01-03 08:26:20
举报
文章被收录于专栏:历史专栏历史专栏

🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。

🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。 🏆🎉欢迎 👍点赞✍评论⭐收藏

🚀前言

DrawString是C#中Graphics类的一个方法,用于在指定的位置绘制文本。在WinForm应用程序中使用DrawString,可以在窗体或控件上绘制文本。

以下是使用DrawString方法在WinForm中绘制文本的示例代码:

代码语言:csharp
复制
private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    string text = "Hello, World!";
    Font font = new Font("Arial", 16);
    Brush brush = Brushes.Black;
    PointF point = new PointF(50, 50);

    g.DrawString(text, font, brush, point);
}

在上面的示例中,我们使用Graphics类的DrawString方法在Form1的Paint事件中绘制了一个文本字符串。我们创建了一个Graphics对象g并在其上调用DrawString方法。方法的第一个参数是要绘制的文本字符串,第二个参数是要使用的字体,第三个参数是绘制文本的刷子(颜色),第四个参数是文本的位置。

您可以根据需要更改字体,颜色和位置等参数,以根据您的应用程序的需要在窗体或控件上绘制文本。

🚀一、DrawString

🔎1.制表位

在GDI+中,通过使用TabStops属性和StringFormat类,可以在绘图时使用像素或百分比的制表位来对齐文本。这对于制作表格和对齐文本非常有用。下面是一个示例代码,演示如何在WinForm中绘制带有制表符的文本。

代码语言:csharp
复制
private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    string text = "Name\tAge\tGender";
    Font font = new Font("Arial", 16);
    Brush brush = Brushes.Black;
    PointF point = new PointF(50, 50);
    StringFormat format = new StringFormat();
    format.SetTabStops(50, new float[] { 100, 200 });

    g.DrawString(text, font, brush, point, format);
}

在上面的示例中,我们使用Graphics类的DrawString方法在Form1的Paint事件中绘制了一个带有制表符的文本字符串。我们创建了一个Graphics对象g,然后定义了文本字符串,字体,笔刷和位置,以及一个StringFormat对象。我们通过在SetTabStops方法中指定像素值和百分比值来设置制表位。在此示例中,我们在50像素处设置了一个制表位,并在100像素的位置和200像素的位置处指定了两个制表符。这将使文本沿x轴对齐,并在“Name”和“Age”之间以及“Age”和“Gender”之间创建制表符。最后,我们在Graphics对象上调用DrawString方法,指定文本,字体,笔刷,位置和格式。

🔎2.使用笔刷显示文本

不仅可以使用GDI+绘图DrawString方法以文本形式在绘图表面上绘制字符。同时,可以使用HatchBrush笔刷来为绘制的文本添加纹理、阴影等效果。

以下是使用HatchBrush笔刷在WinForm中绘制文本的示例代码:

代码语言:csharp
复制
// 创建绘图表面
Bitmap bmp = new Bitmap(200, 200);
Graphics g = Graphics.FromImage(bmp);

// 创建HatchBrush笔刷
HatchBrush hatchBrush = new HatchBrush(HatchStyle.Cross, Color.Green, Color.Yellow);

// 绘制文本
string text = "HatchBrush Test";
Font font = new Font("Arial", 20);
PointF point = new PointF(20, 70);
g.DrawString(text, font, hatchBrush, point);

// 显示绘制结果
pictureBox1.Image = bmp;

上述代码中,首先创建了一个200x200像素大小的位图和相应的Graphics对象。然后创建了一个HatchBrush对象,并将其作为参数传递给DrawString方法,以绘制文本。最后在pictureBox1中显示绘制结果。

运行上述代码后,将看到绘制了“HatchBrush Test”文本的图片,文本的字体颜色为绿黄相间的格子状。

此外,还可以使用其他类型的Brush对象来为绘制的文本添加不同的效果。例如,使用LinearGradientBrush可以为文本添加渐变色效果。

🔎3.精确控制文本

🦋3.1 文本居中

在使用GDI+绘制文本时,可以使用DrawString方法来绘制。该方法有多个重载,其中有一个重载可以通过PointF类型的参数来确定文本的起始绘制位置,如下所示:

代码语言:csharp
复制
public void DrawString(string s, Font font, Brush brush, PointF point);

其中s为要绘制的字符串,font为文字的字体样式,brush为文字的填充颜色,point为文字的起始绘制位置。要精确控制文本的位置,可以使用PointF类型的参数来指定起始位置。

例如,要将字符串"Hello, World!"绘制在WinForm的画布中心位置,可以先计算出文本绘制所需的区域大小,然后将文本绘制起始位置设置为画布中心减去文本绘制区域大小的一半,如下所示:

代码语言:csharp
复制
private void Form1_Paint(object sender, PaintEventArgs e)
{
    string text = "Hello, World!";
    Font font = new Font("Arial", 16);
    Brush brush = Brushes.Black;

    // 计算文本绘制所需的区域大小
    SizeF textSize = e.Graphics.MeasureString(text, font);

    // 计算文本绘制起始位置
    PointF startPoint = new PointF(
        (this.ClientSize.Width - textSize.Width) / 2,
        (this.ClientSize.Height - textSize.Height) / 2);

    // 绘制文本
    e.Graphics.DrawString(text, font, brush, startPoint);
}

在上述代码中,使用Graphics对象的MeasureString方法计算出文本绘制所需的区域大小,然后计算出文本绘制起始位置,并使用DrawString方法进行绘制。这样就可以精确地控制文本的位置。

🦋3.2 精确控制文本

代码语言:csharp
复制
private void OnPaint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.FillRectangle(Brushes.White, this.ClientRectangle);

    FontFamily fontFamily = new FontFamily("宋体");
    int ascentInDU = fontFamily.GetCellAscent(FontStyle.Regular);
    int descentInDU = fontFamily.GetCellDescent(FontStyle.Regular);
    int emHeightInDU = fontFamily.GetEmHeight(FontStyle.Regular);
    int lineSpacingInDU = fontFamily.GetLineSpacing(FontStyle.Regular);

    float emSizeInGU = 100;
    Font font = new Font(fontFamily, emSizeInGU, FontStyle.Regular);

    float ascentInGU = ascentInDU * (emSizeInGU / emHeightInDU);
    float descentInGU = descentInDU * (emSizeInGU / emHeightInDU);
    float lineSpacingInGU = lineSpacingInDU * (emSizeInGU / emHeightInDU);

    HatchBrush hb = new HatchBrush(HatchStyle.Cross, Color.Red);
    PointF textOrig = new PointF(10, 20);
    PointF nextLineTextOrig = new PointF(textOrig.X, textOrig.Y + font.Height);
    g.DrawString("Mg好人", font, hb, textOrig);
    g.DrawString("Mg好人", font, hb, nextLineTextOrig);

    int lineLength = 500;
    g.DrawLine(Pens.Blue, textOrig, new PointF(textOrig.X + lineLength, textOrig.Y));
    g.DrawLine(Pens.Blue, nextLineTextOrig, new PointF(nextLineTextOrig.X + lineLength, nextLineTextOrig.Y));

    PointF p = new PointF(textOrig.X, textOrig.Y + lineSpacingInGU);
    g.DrawLine(Pens.Red, p, new PointF(p.X + lineLength, p.Y));

    g.DrawLine(Pens.Black, new PointF(p.X + lineLength, p.Y), new PointF(p.X + lineLength, p.Y + 153));

    p = new PointF(nextLineTextOrig.X, nextLineTextOrig.Y + lineSpacingInGU);
    g.DrawLine(Pens.Red, p, new PointF(p.X + lineLength, p.Y));

    p = new PointF(textOrig.X, textOrig.Y + lineSpacingInGU - ascentInGU);
    g.DrawLine(Pens.Yellow, p, new PointF(p.X + lineLength, p.Y));
    p = new PointF(nextLineTextOrig.X, nextLineTextOrig.Y + lineSpacingInGU - ascentInGU);
    g.DrawLine(Pens.Yellow, p, new PointF(p.X + lineLength, p.Y));

    p = new PointF(textOrig.X, textOrig.Y + lineSpacingInGU + descentInGU);
    g.DrawLine(Pens.Green, p, new PointF(p.X + lineLength, p.Y));
    p = new PointF(nextLineTextOrig.X, nextLineTextOrig.Y + lineSpacingInGU + descentInGU);
    g.DrawLine(Pens.Green, p, new PointF(p.X + lineLength, p.Y));

    font.Dispose();

}
  • 红色线:基线,蓝色线到红色线之间的距离就是lineSpacingInGU;
  • 绿色线:红色线到绿色线之间的距离就是descentInGU;
  • 黄线色:黄色线到红色线之间的距离就是ascentInGU;
  • 黑色线:指的是两行红色线之间的距离,也就是行距。

🔎4.文本的质量

GDI+绘图DrawString绘制文本时,可以使用TextRenderingHint属性来提高或降低文本的质量和清晰度。以下是使用TextRenderingHint属性的示例:

代码语言:csharp
复制
private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;

    // 设置文本呈现质量为抗锯齿
    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

    // 绘制文本
    string text = "Hello World!";
    Font font = new Font("Arial", 16);
    Brush brush = Brushes.Black;
    PointF point = new PointF(50, 50);

    g.DrawString(text, font, brush, point);
}

在上面的示例中,我们将TextRenderingHint属性设置为抗锯齿,以获得更平滑的文本边缘。如果需要更高的性能,则可以将该属性设置为Default或SystemDefault。但是,这可能会牺牲一些文本呈现的质量。

在设置完TextRenderingHint属性后,可以使用DrawString方法来绘制文本。该方法的参数包括文本内容、字体、笔刷、位置等。使用这些参数,可以控制文本的样式、颜色和位置等属性。

🔎5.处理绘图表面的单位以及字体的单位

代码语言:csharp
复制
private void OnPaint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.PageUnit = GraphicsUnit.Inch;
    Pen p = new Pen(Color.Black, 1 / 96f);
    Font f = new Font("Times New Roman", 16);
    string s = "Abc";
    SizeF sf = g.MeasureString(s, f);

    g.DrawRectangle(p, 1, 1, sf.Width, sf.Height);
    g.DrawString(s, f, Brushes.Black, 1, 1);


    f = new Font("Times New Roman", 1, GraphicsUnit.Inch);
    sf = g.MeasureString(s, f);

    g.DrawRectangle(p, 1, 1, sf.Width, sf.Height);
    g.DrawString(s, f, Brushes.Red, 1, 1);

    f.Dispose();
    p.Dispose();
}

🔎6.测量文本大小

代码语言:csharp
复制
using System.Drawing;
using System.Windows.Forms;

namespace MeasureStringExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            string text = "Hello World";
            Font font = new Font("Arial", 12);
            SizeF size = new SizeF(100, 100);
            Graphics graphics = e.Graphics;
            SizeF textSize = graphics.MeasureString(text, font, size);
            PointF location = new PointF(10, 10);
            graphics.DrawString(text, font, Brushes.Black, location);
            graphics.DrawRectangle(Pens.Red, new RectangleF(location, textSize));
        }
    }
}

在上面的代码中,我们在 Form1_Paint 事件处理程序中使用MeasureString方法来测量一个字符串的大小,然后在屏幕上绘制该字符串并用红色边框标记该字符串的大小。这个例子中测量的字符串是"Hello World",字体是Arial、大小为12磅,并且大小被限制在100x100的矩形区域内。在绘制字符串时,我们将使用黑色刷子,位置位于(10,10)。

🔎7.StringFormat

DrawString方法有多个重载,其中一个参数是StringFormat类型的格式化对象。StringFormat对象可以设置文本的对齐方式、行距、字间距等等。

以下是一个使用StringFormat对象的示例:

代码语言:csharp
复制
private void Form1_Paint(object sender, PaintEventArgs e)
{
    //创建一个StringFormat对象
    StringFormat stringFormat = new StringFormat();
    stringFormat.Alignment = StringAlignment.Center;
    stringFormat.LineAlignment = StringAlignment.Center;

    //绘制文本
    e.Graphics.DrawString("Hello World!", Font, Brushes.Black, 
        new RectangleF(0, 0, ClientSize.Width, ClientSize.Height), 
        stringFormat);
}

在上面的代码中,我们创建了一个StringFormat对象,并设置了Alignment和LineAlignment属性来使文本在控件中央对齐。接着,我们使用Graphics对象的DrawString方法来绘制文本,其中第四个参数是绘制文本的矩形区域,第五个参数是我们创建的StringFormat对象。

可以通过设置StringFormat对象的其他属性,来实现不同的文本效果,例如设置Trimming属性来裁剪超出矩形区域的文本,设置TabStops属性来实现文本的制表符对齐等等。

需要注意的是,在使用StringFormat对象时,需要在绘制文本时将其作为参数传递。否则,将无法应用StringFormat对象的属性。


我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🚀前言
  • 🚀一、DrawString
    • 🔎1.制表位
      • 🔎2.使用笔刷显示文本
        • 🔎3.精确控制文本
          • 🦋3.1 文本居中
          • 🦋3.2 精确控制文本
        • 🔎4.文本的质量
          • 🔎5.处理绘图表面的单位以及字体的单位
            • 🔎6.测量文本大小
              • 🔎7.StringFormat
              相关产品与服务
              云开发 CloudBase
              云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档