我需要在图像上方添加一些文本字符串。我不能用一个块来做这个,因为图标添加到每一行(不在代码示例中)。但由于每个字符串具有不同的长度,因此块之间存在较大间隔或彼此相邻。 如何根据字体大小和字符串长度计算矩形大小?
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);
}
答案 0 :(得分:0)
Graphics.MeasureString()
可以非常精确地计算空间,表示为矩形区域,当在具有指定字体特征和大小限制的已定义设备上下文中绘制时,需要一串文本。
您目前的限制是:
- 由Bitmap尺寸定义的Surface(画布)大小
- 初始边距(左,上)
你没有说文本是否应该在宽度超过时包裹 施加画布宽度。
在这里,我假设它确实如此。
每个字体都有自己的指标。 .MeasureString()
为我们处理这些措施。但是,应指定一些参数来定义渲染的行为和整体质量。
Graphics.TextRenderingHint
属性可用于指定文本的质量
请参阅TextRenderingHint.AntiAliasGridFit
和TextRenderingHint.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));
}
}
这是视觉效果: