c#DrawString-测量每个字符的边界框 [英] c# DrawString - measure bounding boxes for each character
问题描述
在将字符串传递给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屋!