C# 如何精确测量字符宽度?
也许我有点不对劲,但是。。。我想模拟字符间距。 我将单词(文本)分解成单个字符的列表,测量它们的宽度,然后在位图上一个接一个地绘制它们。我想,渲染文本的总宽度将与整个未拆分字符串的宽度相同,但存在一些问题。在循环中渲染字符显示更广泛的结果。有什么方法可以得到共同的(预期的)结果吗 以下是一段代码片段:C# 如何精确测量字符宽度?,c#,.net,width,character,C#,.net,Width,Character,也许我有点不对劲,但是。。。我想模拟字符间距。 我将单词(文本)分解成单个字符的列表,测量它们的宽度,然后在位图上一个接一个地绘制它们。我想,渲染文本的总宽度将与整个未拆分字符串的宽度相同,但存在一些问题。在循环中渲染字符显示更广泛的结果。有什么方法可以得到共同的(预期的)结果吗 以下是一段代码片段: private struct CharWidths { public char Char; public float Width; } private List<CharW
private struct CharWidths
{
public char Char;
public float Width;
}
private List<CharWidths> CharacterWidths = new List<CharWidths>();
私有结构字符宽度
{
公共字符;
公共浮动宽度;
}
私有列表字符宽度=新列表();
private void GetCharacterWidths(字符串文本、位图BMP)
{
int i;
int l=文本长度;
CharacterWidths.Clear();
Graphics g=Graphics.FromImage(BMP);
CharWidths cw=新的CharWidths();
对于(i=0;i
public void渲染位图(位图BMP)
{
//MessageBox.Show(“颜色”);
Graphics g=Graphics.FromImage(BMP);
GetCharacterWidths(“Lyborko”,BMP);
int i;
浮动X=0;
PointF P=新的PointF();
对于(i=0;i
Thanx很多首先应该说,没有解决这个问题的灵丹妙药,但有一些关于这个问题的建议:
TextRenderer.MeasureText
不会传递当前设备上下文
(与您在后面绘制字符串时使用的上下文相同)知道了一个简单的事实,MeasureText
仅在缺少该参数的情况下创建一个与桌面兼容的新参数,并调用DrawTextEx
windowsdk函数,我想说,首先在指定的地方使用重载,比如第一个参数设备上下文
,然后用它来呈现文本。可能会有所不同希望这能有所帮助。一旦你遇到了“不寻常”的角色,你的方法就注定要失败。例如,存在组合字符,其中多个代码点在屏幕上呈现为单个符号。您的代码还将文本拆分为UTF-16代码单位,而不是代码点。@CodeInChaos Ok,这肯定不是最好的,但我应该怎么做?这个问题很好地说明了为什么这样做不起作用:测量字符串,而不是字符。我试着按照您的建议指定DeviceContext:Size textSize=TextRenderer.MeasureText(g,text[I].ToString(),Font);但是没有发生变化…@lyborko:那么第二种选择呢?第二种选择我没有试过。通过设置TextFlags,我获得了显著的效果,但差异仍然是可见的(尽管是像素)。请参阅:TextFormatFlags flags=TextFormatFlags.noppadding;尺寸si=新尺寸(1,1);Size textSize=TextRenderer.MeasureText(g,Text[i].ToString(),Font,si,flags);
private void GetCharacterWidths(string Text, Bitmap BMP)
{
int i;
int l = Text.Length;
CharacterWidths.Clear();
Graphics g = Graphics.FromImage(BMP);
CharWidths cw = new CharWidths();
for (i = 0; i < l; i++)
{
Size textSize = TextRenderer.MeasureText(Text[i].ToString(), Font);
cw.Char = Text[i];
cw.Width = textSize.Width;
CharacterWidths.Add(cw);
}
}
public void RenderToBitmap(Bitmap BMP)
{
//MessageBox.Show("color");
Graphics g = Graphics.FromImage(BMP);
GetCharacterWidths("Lyborko", BMP);
int i;
float X = 0;
PointF P = new PointF();
for (i = 0; i < CharacterWidths.Count; i++)
{
P.X = X;
P.Y = 0;
g.DrawString(CharacterWidths[i].Char.ToString(), Font, Brushes.White, P);
X = X+CharacterWidths[i].Width;
}
P.X = 0;
P.Y = 30;
g.DrawString("Lyborko", Font, Brushes.White, P);
// see the difference
}