Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 测量位图中数字的宽度_C#_.net_Bitmap_Character - Fatal编程技术网

C# 测量位图中数字的宽度

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))

我创建了一个用于绘制任意数字的纹理(位图)

纹理包含文本: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));
添加('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):