How to draw a string at an exact pixel position

独自空忆成欢 提交于 2019-12-02 01:39:58

No need to look at the pixels or start working with your own font..

You can use a GraphicsPath instead of DrawString or TextRenderer, as it will let you know its net bounds rectangle with GraphicsPath.GetBounds() .

When you know it, you can calculate how to move the Graphics object using TranslateTransform:

private void button1_Click(object sender, EventArgs e)
{
    string text = "Y";                  // whatever
    Bitmap bmp = new Bitmap(64, 64);    // whatever
    bmp.SetResolution(96, 96);          // whatever
    float fontSize = 32f;               // whatever

    using ( Graphics g = Graphics.FromImage(bmp))
    using ( GraphicsPath GP = new GraphicsPath())
    using ( FontFamily fontF = new FontFamily("Arial"))
    {
        testPattern(g, bmp.Size);      // optional

        GP.AddString(text, fontF, 0, fontSize, Point.Empty,
                     StringFormat.GenericTypographic);
        // this is the net bounds without any whitespace:
        Rectangle br = Rectangle.Round(GP.GetBounds());

        g.DrawRectangle(Pens.Red,br); // just for testing

        // now we center:
        g.TranslateTransform( (bmp.Width - br.Width )  / 2 - br.X,
                              (bmp.Height - br.Height )/ 2 - br.Y);
        // and fill
        g.FillPath(Brushes.Black, GP);
        g.ResetTransform();
    }

    // whatever you want to do..
    pictureBox1.Image = bmp;
    bmp.Save("D:\\__test.png", ImageFormat.Png);

}

A small test routine to let us see the centering better:

void testPattern(Graphics g, Size sz)
{
    List<Brush> brushes = new List<Brush>() 
    {   Brushes.SlateBlue, Brushes.Yellow, 
        Brushes.DarkGoldenrod, Brushes.Lavender };
    int bw2 = sz.Width / 2;
    int bh2 = sz.Height / 2;
    for (int i = bw2; i > 0; i--)
        g.FillRectangle(brushes[i%4],bw2 - i, bh2 - i, i + i, i + i );

}

The GetBounds method returns a RectangleF; in my example it is {X=0.09375, Y=6.0625, Width=21, Height=22.90625}. Do note that due to rounding things can always be off by one..

You may or may not want to change the Graphics setting to special Smoothingmodes etc..

Also it should be noted that this will do automatic ie mechanical centering by the bounds rectangle. This may be quite different from 'optical or visual centering', which is rather hard to code and to some extent a matter of personal taste. But typography is as much an art as a profession..

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!