You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在C#中使用DrawString实现文本完美垂直居中的问题

我太懂这个痛点了!用MeasureString做水平居中确实没毛病,但它返回的高度是字体的全行高范围——包含了大写字母的顶部预留空间、小写字母的底部延伸空间,哪怕你的字符串全是小写或者没有上下延伸的字符,它也会返回最大可能的高度,导致垂直居中总是有点“飘”,视觉上不精准。

给你两个实用的解决方案,看你习惯哪种:

方案一:用TextRenderer获取真实文本尺寸(精准首选)

TextRenderer的测量逻辑更贴近实际渲染的文本边界,返回的尺寸就是当前字符串实际占据的像素大小,没有多余留白。代码示例:

using (Graphics gr = Graphics.FromImage(mBackImage))
{
    gr.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    // 先填充背景(示例)
    gr.FillRectangle(new SolidBrush(Color.White), gr.ClipBounds);

    string targetText = "你要居中的字符串";
    Font textFont = new Font("微软雅黑", 14);
    Brush textBrush = new SolidBrush(Color.DarkSlateGray);

    // 获取精准的文本实际尺寸
    Size textActualSize = TextRenderer.MeasureText(gr, targetText, textFont);

    // 计算完全居中的坐标
    int centerX = (mBackImage.Width - textActualSize.Width) / 2;
    int centerY = (mBackImage.Height - textActualSize.Height) / 2;

    // 绘制文本
    TextRenderer.DrawText(gr, targetText, textFont, new Point(centerX, centerY), Color.DarkSlateGray);
}

方案二:用StringFormat让GDI+自动居中(更简洁)

如果你不想换测量方式,直接用DrawString配合StringFormat设置对齐方式,让GDI+帮你处理垂直居中的细节,虽然MeasureString的高度还是全行高,但视觉上会精准居中:

using (Graphics gr = Graphics.FromImage(mBackImage))
{
    gr.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    gr.FillRectangle(new SolidBrush(Color.White), gr.ClipBounds);

    string targetText = "你要居中的字符串";
    Font textFont = new Font("微软雅黑", 14);
    Brush textBrush = new SolidBrush(Color.DarkSlateGray);

    // 设置文本对齐方式:水平+垂直都居中
    StringFormat centerFormat = new StringFormat();
    centerFormat.Alignment = StringAlignment.Center;
    centerFormat.LineAlignment = StringAlignment.Center;

    // 用整个图像区域作为布局矩形,GDI+会自动把文本放在中心
    RectangleF layoutArea = new RectangleF(0, 0, mBackImage.Width, mBackImage.Height);
    gr.DrawString(targetText, textFont, textBrush, layoutArea, centerFormat);
}

额外小tip

如果需要极致精准到字符级的边界,可以用Graphics.MeasureCharacterRanges来获取每个字符的具体区域,但大部分业务场景下上面两个方案完全够用啦。

内容的提问来源于stack exchange,提问作者Sierramike

火山引擎 最新活动