如何获取文本块的大小?

时间:2018-03-11 17:41:10

标签: c# graphics fonts

我需要在图像上方添加一些文本字符串。我不能用一个块来做这个,因为图标添加到每一行(不在代码示例中)。但由于每个字符串具有不同的长度,因此块之间存在较大间隔或彼此相邻。 如何根据字体大小和字符串长度计算矩形大小?

Bitmap bmp = new Bitmap(w,h);
Graphics grp = Graphics.FromImage(bmp);

Color color = colors[0];
Brush brush = new SolidBrush(color);
Font font = new System.Drawing.Font("Arial", 30, FontStyle.Bold, GraphicsUnit.Pixel);
SizeF textSize = new SizeF();
textSize = grp.MeasureString(text[0], font);
System.Drawing.StringFormat stringFormat = new StringFormat();

for (int i = 0; i < 5; i++) {
    grp.DrawString(text[i], font, brush, new RectangleF(60, h + i*step, (int)(w*0.5)-50, step), stringFormat);
}

1 个答案:

答案 0 :(得分:0)

Graphics.MeasureString()可以非常精确地计算空间,表示为矩形区域,当在具有指定字体特征和大小限制的已定义设备上下文中绘制时,需要一串文本。

您目前的限制是:
- 由Bitmap尺寸定义的Surface(画布)大小 - 初始边距(左,上)

  

你没有说文本是否应该在宽度超过时包裹   施加画布宽度。
在这里,我假设它确实如此。

每个字体都有自己的指标。 .MeasureString()为我们处理这些措施。但是,应指定一些参数来定义渲染的行为和整体质量。

Graphics.TextRenderingHint属性可用于指定文本的质量 请参阅TextRenderingHint.AntiAliasGridFitTextRenderingHint.ClearTypeGridFit及其差异。后者代表了最高质量。尽管如此,它的结果可能会在某些情况下失去预期。例如,在透明表面上绘图时。

在目前的情况下,我正在使用TextRenderingHint.AntiAliasGridFit。在我看来,在这种情况下,它的渲染在视觉上更好。如果你在纸上打印会有所不同。

StringFormat() Flags用于改变文本处置对其测量的影响方式 这里,StringFormatFlags.LineLimit(1)和StringFormatFlags.MeasureTrailingSpaces(2)用于验证(1)垂直度量是否正确(否则,包装字符串的最后一行将被剪裁)并查看是否尾随空格(2)的存在会导致意外的自动换行 如果没有提到自动换行,请使用StringFormatFlags.NoWrap标志。

  

请注意,在以下代码中,定义了文本绘图位置   由:

PointF(LeftMargin, TextVerticalPosition)
  

文本块(矩形)大小由以下定义:

RectangleF(TextPosition, TextSize)
  

此度量可用于绘制起点附近的其他对象   一行文字。

string[] TextLines = new string[] { "First Line of Text", 
                                    "Secon Line of Text a bit larger than the one before", 
                                    "Third Line of Text, this is mid-sized." };

using (Bitmap bitmap = new Bitmap(280, 200))
{
    using (Graphics graphics = Graphics.FromImage(bitmap))
    {
        Font font = new Font("Calibri", 22, FontStyle.Regular, GraphicsUnit.Pixel);

        graphics.Clear(Color.Goldenrod);
        graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
        graphics.TextContrast = 10;
        StringFormat stringformat = new StringFormat(StringFormatFlags.LineLimit | 
                                                     StringFormatFlags.MeasureTrailingSpaces);
        stringformat.Trimming = StringTrimming.Word;

        float LineSpacing = 10.0F;
        float LeftMargin = 30F;
        float TextVerticalPosition = 10F;

        for (int i = 0; i < 3; i++)
        {
            SizeF TextSize = graphics.MeasureString(TextLines[i], font, (bitmap.Width - (int)LeftMargin), stringformat);
            PointF TextPosition = new PointF(LeftMargin, TextVerticalPosition);
            graphics.DrawString(TextLines[i], 
                                font, 
                                new SolidBrush(Color.Black),
                                new RectangleF(TextPosition, TextSize), 
                                StringFormat.GenericTypographic);
            TextVerticalPosition += TextSize.Height + LineSpacing;
        }
        graphics.Save();
        font.Dispose();
        graphics.DrawImage(bitmap, new Point(0, 0));
    }
}

这是视觉效果:

enter image description here