在位图中测量数字的宽度

时间:2014-06-26 09:54:23

标签: c# .net bitmap character

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

纹理包含文本:0123456789 .-

Actual Image

现在我需要每个角色的坐标。

TextRenderer.MeasureText(c.ToString(), m_font, new Size(1, 1), TextFormatFlags.NoPadding);

...返回是16x17

g.MeasureString(c.ToString(), m_font);

...回报是11.9x17.7

实际尺寸为8x11

我现在的解决方法是对每个字符进行手动测量,得出下表: coords.Add('0', new RectangleF(1, 3, 8, 11)); coords.Add('1', new RectangleF(9, 3, 7, 11)); coords.Add('2', new RectangleF(15, 3, 8, 11)); coords.Add('3', new RectangleF(22, 3, 8, 11)); coords.Add('4', new RectangleF(29, 3, 8, 11)); coords.Add('5', new RectangleF(36, 3, 8, 11)); coords.Add('6', new RectangleF(43, 3, 8, 11)); coords.Add('7', new RectangleF(50, 3, 8, 11)); coords.Add('8', new RectangleF(57, 3, 8, 11)); coords.Add('9', new RectangleF(64, 3, 8, 11)); coords.Add('.', new RectangleF(72, 3, 3, 11)); coords.Add('-', new RectangleF(75, 3, 6, 11));

我想使用动态字体,因此需要采用编程方式来测量大小。

1 个答案:

答案 0 :(得分:1)

告诉MeasureString方法使用泛型排版StringFormat。

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函数中显然存在错误。如果在没有StringFormatFlags.DirectionRightToLeft的情况下调用MeasureString,则忽略字符“Te”的重叠。

enter image description here