C# 测量位图中数字的宽度
我创建了一个用于绘制任意数字的纹理(位图) 纹理包含文本:0123456789- 现在我需要每个字符的坐标C# 测量位图中数字的宽度,c#,.net,bitmap,character,C#,.net,Bitmap,Character,我创建了一个用于绘制任意数字的纹理(位图) 纹理包含文本:0123456789- 现在我需要每个字符的坐标 textrender.MeasureText(c.ToString(),m_字体,新大小(1,1),TextFormatFlags.NoPadding) …返回值为16x17 g.MeasureString(c.ToString(),m_字体) …返回值为11.9x17.7 实际大小为8x11 我目前的解决方法是手动测量每个字符,得出下表: 添加('0',新矩形F(1,3,8,11))
textrender.MeasureText(c.ToString(),m_字体,新大小(1,1),TextFormatFlags.NoPadding)代码>
…返回值为16x17
g.MeasureString(c.ToString(),m_字体)代码>
…返回值为11.9x17.7
实际大小为8x11
我目前的解决方法是手动测量每个字符,得出下表:
添加('0',新矩形F(1,3,8,11));
添加('1',新矩形F(9,3,7,11));
添加('2',新矩形F(15,3,8,11));
添加('3',新矩形F(22,3,8,11));
添加('4',新矩形F(29,3,8,11));
添加('5',新矩形F(36,3,8,11));
添加('6',新矩形F(43,3,8,11));
添加('7',新矩形F(50,3,8,11));
添加('8',新矩形F(57,3,8,11));
添加('9',新矩形F(64,3,8,11));
添加('.',新矩形F(72,3,3,11));
添加('-',新矩形F(75,3,6,11))代码>
我想使用动态字体,因此需要一种编程方式来测量大小。告诉MeasureString方法使用通用的排版格式
static void Main(string[] args)
{
var image = new Bitmap(1000, 500);
var g = Graphics.FromImage(image);
g.FillRectangle(System.Drawing.Brushes.White, 0, 0, 1000, 500);
var stringFormat = new StringFormat(StringFormat.GenericTypographic) {
Alignment = StringAlignment.Near,
FormatFlags = System.Drawing.StringFormatFlags.LineLimit | System.Drawing.StringFormatFlags.NoClip | StringFormatFlags.DirectionRightToLeft
};
var font = new Font(new System.Drawing.FontFamily("Times New Roman"), 72.0f,FontStyle.Regular, GraphicsUnit.Point);
var point = new PointF { X = 10, Y = 10 };
SizeF[] outputs = new SizeF[7];
SizeF[] total = new SizeF[7];
outputs[0] = g.MeasureString("T", font, point, stringFormat);
outputs[1] = g.MeasureString("e", font, point, stringFormat);
outputs[2] = g.MeasureString("s", font, point, stringFormat);
outputs[3] = g.MeasureString("t", font, point, stringFormat);
outputs[4] = g.MeasureString("S", font, point, stringFormat);
outputs[5] = g.MeasureString("t", font, point, stringFormat);
outputs[6] = g.MeasureString("r", font, point, stringFormat);
total[0] = g.MeasureString("T", font, point, stringFormat);
total[1] = g.MeasureString("Te", font, point, stringFormat);
total[2] = g.MeasureString("Tes", font, point, stringFormat);
total[3] = g.MeasureString("Test", font, point, stringFormat);
total[4] = g.MeasureString("TestS", font, point, stringFormat);
total[5] = g.MeasureString("TestSt", font, point, stringFormat);
total[6] = g.MeasureString("TestStr", font, point, stringFormat);
stringFormat.FormatFlags = System.Drawing.StringFormatFlags.LineLimit | System.Drawing.StringFormatFlags.NoClip;
g.DrawString("TestStr", font, System.Drawing.Brushes.Red, new PointF { X = 10, Y = 10 }, stringFormat);
g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Brushes.Blue, 1.0f), GetOutputPositionX(total,outputs, 0), 10.0f, outputs[0].Width, outputs[0].Height);
g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Brushes.Blue, 1.0f), GetOutputPositionX(total,outputs, 1), 10.0f, outputs[1].Width, outputs[1].Height);
g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Brushes.Blue, 1.0f), GetOutputPositionX(total,outputs, 2), 10.0f, outputs[2].Width, outputs[2].Height);
g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Brushes.Blue, 1.0f), GetOutputPositionX(total,outputs, 3), 10.0f, outputs[3].Width, outputs[3].Height);
g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Brushes.Blue, 1.0f), GetOutputPositionX(total,outputs, 4), 10.0f, outputs[4].Width, outputs[4].Height);
g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Brushes.Blue, 1.0f), GetOutputPositionX(total,outputs, 5), 10.0f, outputs[5].Width, outputs[5].Height);
g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Brushes.Blue, 1.0f), GetOutputPositionX(total,outputs, 6), 10.0f, outputs[6].Width, outputs[6].Height);
image.Save(@"c:\Temp\bla.png");
}
private static float GetOutputPositionX(SizeF[] total, SizeF[] outputs, int p)
{
return 10.0f + total[p].Width - outputs[p].Width;
}
为了准确获得位置,由于这些重叠字符,您必须计算“e”的宽度和“Te”的总宽度
另外,MeasureString函数中显然存在一个bug。如果在不使用StringFormatFlags.DirectionRightToLeft的情况下调用MeasureString,则忽略字符“Te”的重叠
我认为您必须寻找更多的过载。想象一下你正在测量一个i。你怎么知道点是i的一部分,而不是一个单独的字符。也许你得到了意想不到的值,因为在调用函数时它也包含了行高。我无法让它工作。我采用了精确的代码并将其放入新的解决方案中,但在我的情况下,绿色网格的对齐是错误的。您能再检查一下吗?@testalino您能添加您的输出图像吗。@testalino我以前在WPF应用程序中测试过,效果很好。在控制台应用程序中,GDI与字符“Te”重叠。无论出于何种原因,WPF应用程序中都不会发生这种情况。我已经更新了我的代码。好的,非常感谢你在这方面所做的工作。我可以得到相同的结果,你张贴时使用你的代码。尽管它在我的环境中仍然不起作用,因为当你降低字体大小时,框架突然不再适合字母,可能是因为像素的舍入。使用我的实际字体时尤其如此(Tahoma,10):