首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在精确的像素位置绘制字符串

如何在精确的像素位置绘制字符串
EN

Stack Overflow用户
提问于 2015-10-15 12:25:32
回答 1查看 1.7K关注 0票数 2

我试图将C#中的字符串(单个字符)绘制到位图中,其精确位置如下:

代码语言:javascript
复制
Bitmap bmp = new Bitmap(64, 64);
Graphics g = Graphics.FromImage(bmp);
g.DrawString("W", font1, new SolidBrush(myColor), new Point(32,32);

在一个字母周围有如此多的空空间,以至于我猜不出画字符的“所需”的位置,使它在结尾的位置正确。

到目前为止,我已经得到了字符的像素精确尺寸(查看单独呈现的位图中的位)。但是这个信息是无用的,如果我不能在一个确切的位置画字符(例如中间或右上角或.)。

是否有其他方法在位图上用C#绘制文本?或者是否有任何转换方法来转换DrawString需要的真实像素位置?

EN

回答 1

Stack Overflow用户

发布于 2015-10-15 15:13:48

无需查看像素或开始使用自己的字体。

您可以使用GraphicsPath而不是DrawStringTextRenderer,因为它会让您知道它的网络边界矩形GraphicsPath.GetBounds()

知道之后,就可以计算如何使用Graphics移动TranslateTransform对象。

代码语言:javascript
复制
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);

}

一个小的测试程序,让我们更好地看到中心:

代码语言:javascript
复制
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 );

}

GetBounds方法返回一个RectangleF;在我的示例中,它是{X=0.09375, Y=6.0625, Width=21, Height=22.90625}。请注意,由于四舍五入的原因,事情总是可以由一个..。

您可能希望或不希望将Graphics设置更改为特殊的Smoothingmodes等。

此外,应该注意的是,这将实现自动的机械对中的边界矩形。这可能与“光学或视觉对中”非常不同,后者很难编写代码,而且在某种程度上是个人品味的问题。但排版既是一门艺术,也是一门职业。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33148543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档