c#DrawString-测量每个字符的边界框 [英] c# DrawString - measure bounding boxes for each character

查看:73
本文介绍了c#DrawString-测量每个字符的边界框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将字符串传递给Graphics.DrawString()之前,我想确切地知道每个字符的位置-不仅是偏移量和宽度,还包括它的精确的装订框,其中包含了上升/下降的数字,以便我可以在字符级别进行碰撞检测,而不是使用Graphics.MeasureString()给我的整个行高.

Before I pass a string to Graphics.DrawString(), I'd like to know exactly where each character will be - not just it's offset and width, but its exact bound box with ascent/descent figured in so that I can do collision detection at the character level rather than using the entire line-height that Graphics.MeasureString() is giving me.

我似乎找不到任何可以准确返回每个字符边界框的示例.如何在c#/GDI +中完成此操作?

I can't seem to find any examples for this that accurately return the bounding box for each character. How can this be done in c#/GDI+ ?

理想情况下,我想获得这张图中的每个灰色矩形:

Ideally, I'd like to get each of the gray Rectangles as in this image:

推荐答案

这是我使用的解决方案,以@Sayka的示例为基础,并提供了获取实际字符宽度的技巧:

This is the solution I used, building on @Sayka's example and a trick to get actual char width:

如果要使用图形g1中的字体在X,Y处绘制字符串,则可以使用以下矩形绘制每个字符:

If you're drawing a string at X, Y using Font in Graphics g1, you can draw each char using these Rectangles:

public IEnumerable<Rectangle> GetRectangles(Graphics g1)
{
    int left = X;
    foreach (char ch in word)
    {

        //actual width is the (width of XX) - (width of X) to ignore padding
        var size = g1.MeasureString("" + ch, Font);
        var size2 = g1.MeasureString("" + ch + ch, Font);

        using (Bitmap b = new Bitmap((int)size.Width + 2, (int)size.Height + 2))
        using (Graphics g = Graphics.FromImage(b))
        {
            g.FillRectangle(Brushes.White, 0, 0, size.Width, size.Height);
            g.TextRenderingHint = g1.TextRenderingHint;
            g.DrawString("" + ch, Font, Brushes.Black, 0, 0);
            int top = -1;
            int bottom = -1;

            //find the top row
            for (int y = 0; top < 0 && y < (int)size.Height - 1; y++)
            {
                for (int x = 0; x < (int)size.Width; x++)
                {
                    if (b.GetPixel(x, y).B < 2)
                    {
                        top = y;
                    }
                }
            }

            //find the bottom row
            for (int y = (int)(size.Height - 1); bottom < 0 && y > 1; y--)
            {
                for (int x = 0; x < (int)size.Width - 1; x++)
                {
                    if (b.GetPixel(x, y).B < 2)
                    {
                        bottom = y;
                    }
                }
            }
            yield return new Rectangle(left, Y + top, (int)(size2.Width - size.Width), bottom - top);
        }
        left += (int)(size2.Width - size.Width);
    }

}

看起来像这样:

这篇关于c#DrawString-测量每个字符的边界框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆