C# 用抽绳将单个字符居中

C# 用抽绳将单个字符居中,c#,winforms,gdi+,centering,drawstring,C#,Winforms,Gdi+,Centering,Drawstring,我已经尝试了所有建议的文本居中的方法,但在将单个字符居中时,我似乎无法得到想要的结果 我有一个长方形。在那个长方形中,我用抽屉画了一个圆。现在我想用相同的矩形和抽绳在圆内画一个字符,使它完全居中 这是我的基本代码: StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.LineAlignment = StringAlignment.

我已经尝试了所有建议的文本居中的方法,但在将单个字符居中时,我似乎无法得到想要的结果

我有一个长方形。在那个长方形中,我用抽屉画了一个圆。现在我想用相同的矩形和抽绳在圆内画一个字符,使它完全居中

这是我的基本代码:

StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;

using (Graphics g = Graphics.FromImage(xImage))
{
    g.SmoothingMode = SmoothingMode.AntiAlias;
    g.TextRenderingHint = TextRenderingHint.AntiAlias;
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.PixelOffsetMode = PixelOffsetMode.HighQuality;

    g.FillEllipse(fillBrush, imageRect.X, imageRect.Y, imageRect.Width - 1, imageRect.Height - 1);

    g.DrawString(Text, font, Brushes.White, imageRect, stringFormat);
}
文本水平居中。。。但它并没有真正正确地居中。使用像大写字母“I”这样的对称字符,我发现字符的顶部总是比底部更靠近矩形的边缘。距离可能至少增加了50%

我假设它测量的是足够的字符空间,比如挂得更低的小写字母“j”。但是,由于我试图创建一个带有单个字母的图形图标,因此我需要更精确的居中。

如果您使用

StringFormat stringFormat = new StringFormat(StringFormat.GenericTypographic);
你有

反而


希望这有助于使用
GraphicsPath
完成尺寸计算

public static void DrawCenteredText(Graphics canvas, Font font, float size, Rectangle bounds, string text)
{
    var path = new GraphicsPath();
    path.AddString(text, font.FontFamily, (int)font.Style, size, new Point(0, 0), StringFormat.GenericTypographic);

    // Determine physical size of the character when rendered
    var area = Rectangle.Round(path.GetBounds());

    // Slide it to be centered in the specified bounds
    var offset = new Point(bounds.Left + (bounds.Width / 2 - area.Width / 2) - area.Left, bounds.Top + (bounds.Height / 2 - area.Height / 2) - area.Top);
    var translate = new Matrix();
    translate.Translate(offset.X, offset.Y);
    path.Transform(translate);

    // Now render it however desired
    canvas.SmoothingMode = SmoothingMode.AntiAlias;
    canvas.FillPath(SystemBrushes.ControlText, path);
}

尽管John Arlen的答案非常完美,但我想发布我的答案:

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
         // Set up string.
        string measureString = "HelloWorld";
        Font stringFont = new Font("Arial", 100, FontStyle.Regular, GraphicsUnit.Pixel);

        // Measure string.
        SizeF stringSize = new SizeF();
        stringSize = e.Graphics.MeasureString(measureString, stringFont);

        // Draw rectangle representing size of string.
        e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 10.0F, 10.0F, stringSize.Width, stringSize.Height);

        // Draw string to screen.
        e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(10, 10f + stringSize.Height / 12.0f));
    }
代码结果如下:

“HelloWorld”在红色框中垂直居中

因为下降线的高度大约等于
stringSize.height的1/6,通过
MeasureString


|顶部填充1/6 |字体3/6 |字下降器1/6
|底部填充1/6是否将DrawString方法的结果与TextRenderer.DrawText方法的结果进行比较,其中TextFormatFlags为HoriztonalCenter和VerticalCenter?无复制。请注意,大写字母I没有像字符g那样的派生词。我尝试了TextRenderer.DrawText并得到了类似的结果。汉斯:我的观点是,当我绘制没有派生词的字符时,它们垂直居中,为不存在的派生词提供了空白。因此,字符没有真正居中。我假设GDI没有办法做到这一点,所以我要做的是测量文本,创建一个测量大小的位图,在位图上绘制文本,锁定位,并获得实际包含数据(不透明像素)的子矩形的边界区域。然后在第一个矩形的中心位置对该矩形进行位blit。我想应该行得通,但性能会很糟糕。注意你的图片中的“g”并没有居中。我不是在寻找排版居中,我不是在画需要对齐字符的单词。我画的是一个单独的字符,我希望它在圆的正中心,不管它是哪个字符。想象一下平面设计师如何在Photoshop中通过居中来制作图标。我需要通过编程来完成。好吧,我输了,约翰·阿伦有一个完美的答案!它应该是StringFormat StringFormat=新的StringFormat(StringFormat.GenericTypographic());真是天才。我来试试。@C你说得对,这太完美了!我尝试了
MeasureString
,但没有任何运气。今天我找到了这个答案。这个问题由来已久,但问题是实际存在的。这马上就解决了!很酷+1-GraphicsPath被低估(连同标签…);-)这应该引起更多的注意,我为此花了几个小时:)