如何在精确高度绘制给定角色?

时间:2015-03-06 06:31:40

标签: c# graphics

我使用Graphics.DrawString()方法绘制文本,但绘制的文本高度与我给出的不一样。

对于Eg:

Font F=new Font("Arial", 1f,GraphicUnit.Inch);
g.DrawString("M", F,Brushes.red,new Point(0,0));

通过使用上面的代码,我正在绘制高度为1英寸的文本,但绘制的文本并不完全是1英寸。

我需要在我给出的精确高度中绘制文本。提前谢谢..

1 个答案:

答案 0 :(得分:2)

最简单的解决方案是使用GraphicsPath。以下是必要的步骤:

  • 计算您想要的高度(以像素为单位):要获得1.0英寸的距离,比如150 dpi,则需要150像素。

  • 然后创建GraphicsPath并使用计算出的高度添加要使用的字体和字体样式的字符或字符串

  • 现在使用GetBounds测量生成的高度。

  • 然后将高度缩放到必要的像素数

  • 最后清除路径并使用新高度

  • 再次添加字符串
  • 现在您可以使用FillPath输出像素..

这是一个代码示例。它将测试字符串写入文件。如果要使用Graphics对象将其写入打印机或控件,则可以采用相同的方式进行操作;在计算高度的第一个估计值之前,只需获取/设置dpi

下面的代码创建了这个文件; Consolas' x'高度为150像素,因为Wingdings字体的第二个字符(ox95)。 (请注意,我没有将输出居中):

One inch X enter image description here

// we are using these test data:
int Dpi = 150;
float targetHeight = 1.00f;
FontFamily ff = new FontFamily("Consolas");
int fs = (int) FontStyle.Regular;
string targetString = "X";

// this would be the height without the white space
int targetPixels = (int) targetHeight * Dpi;

// we write to a Btimpap. I make it large enough..
// Instead you can write to a printer or a Control surface..
using (Bitmap bmp = new Bitmap(targetPixels * 2, targetPixels * 2))
{
    // either set the resolution here
    // or get and use it above from the Graphics!
    bmp.SetResolution(Dpi, Dpi);
    using (Graphics G = Graphics.FromImage(bmp))
    {
        // good quality, please!
        G.SmoothingMode = SmoothingMode.AntiAlias;
        G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        // target position (in pixels)
        PointF p0 = new PointF(0, 0);
        GraphicsPath gp = new GraphicsPath();
        // first try:
        gp.AddString(targetString, ff, fs, targetPixels, p0,
                     StringFormat.GenericDefault);
        // this is the 1st result
        RectangleF gbBounds = gp.GetBounds();
        // now we correct the height:
        float tSize = targetPixels * targetPixels / gbBounds.Height;
        // and if needed the location:
        p0 = new PointF(p0.X  - gbBounds.X, p0.X - gbBounds.Y);
        // and retry
        gp.Reset();
        gp.AddString(targetString, ff, fs, tSize, p0, StringFormat.GenericDefault);
        // this should be good
        G.Clear(Color.White);
        G.FillPath(Brushes.Black, gp);
    }
    //now we save the image 
    bmp.Save("D:\\testString.png", ImageFormat.Png);
}

您可能希望尝试使用修正系数来放大Font尺寸,然后使用DrawString

还有一种方法可以使用FontMetrics来计算前面的数字,但我理解这种方法可能与字体有关的链接。