从图像上绘制的文本中删除顶部和底部填充
Remove top and bottom padding from Text drawn on an Image
我正在从指定的文本生成图像,但我遇到了一个问题:我无法删除我生成的图像中绘制文本的顶部和底部填充。
我试图在使用 Graphics.DrawString()
时更改字符串格式,但我只设法删除了左右填充。
private void button1_Click(object sender, EventArgs e)
{
Font font = new Font("Arial", 52, FontStyle.Regular);
Image i = GetTextAsImage(textBox1.Text,400, font, Color.Black, Color.LightGray);
i.Save("myImage.jpeg", ImageFormat.Jpeg);
}
private Image GetTextAsImage(String text, int widthInPixel, Font textFont, Color textColor, Color backColor)
{
//first, create a dummy bitmap just to get a graphics object
Image img = new Bitmap(1, 1);
Graphics drawing = Graphics.FromImage(img);
//measure the string to see how big the image needs to be
SizeF textSize = drawing.MeasureString(text, textFont);
//free up the dummy image and old graphics object
img.Dispose();
drawing.Dispose();
//create a new image of the right size
img = new Bitmap((int)textSize.Width, textFont.Height);
drawing = Graphics.FromImage(img);
drawing.SmoothingMode = SmoothingMode.AntiAlias;
drawing.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
//paint the background
drawing.Clear(backColor);
//create a brush for the text
Brush textBrush = new SolidBrush(textColor);
drawing.DrawString(text, textFont, textBrush, 0, 0,StringFormat.GenericTypographic);
drawing.Save();
textBrush.Dispose();
drawing.Dispose();
return img;
}
这是我得到的输出:
这是预期的输出:
我建议您使用一种稍微不同的方法,使用 GraphicsPath class 在位图对象上测量和绘制文本。
优点是 GraphicsPath
class 报告其引用的对象将被绘制的实际坐标以及与特定字体相关的文本大小。
这些度量使用 GraphicsPath.GetBounds() 方法在 RectagleF
结构中返回。
基本构造函数假定 Pen 大小为 1 像素。
只有一个(小)细节需要注意:GDI+ 位图对象只接受以整数值表示的维度,而所有其他度量均以浮点值表示。
我们需要对舍入进行补偿,但通常只是 ± 1 像素。
结果示例:
程序说明:
- 定义字体系列和大小
- 将文本字符串添加到
GraphicsPath
对象
- 获取文本对象的
GraphicsPath
外接矩形
- 使用边界矩形大小构建位图对象
- 将世界坐标 Graphics.TranslateTransform 移动到由边界矩形
Y
位置和笔大小定义的坐标,使用它们的 负值 : 我们需要 向后移动 该措施。
- 绘制文本
另请参阅这些关于 GraphicsPath
和字体的注释:
示例代码:
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
string text = "This is my Text";
Font font = new Font("Arial", 52, FontStyle.Regular, GraphicsUnit.Point);
float penSize = 1f;
using (var path = new GraphicsPath()) {
path.AddString(text, font.FontFamily, (int)font.Style, font.Size, Point.Empty, StringFormat.GenericTypographic);
RectangleF textBounds = path.GetBounds();
using (var bitmap = new Bitmap((int)textBounds.Width, (int)textBounds.Height, PixelFormat.Format32bppArgb))
using (var g = Graphics.FromImage(bitmap))
using (var brush = new SolidBrush(Color.LightGreen)) {
g.SmoothingMode = SmoothingMode.AntiAlias;
// When rendering without a GraphicsPath object
//g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
g.Clear(Color.Black);
g.TranslateTransform(-(textBounds.X + penSize), -(textBounds.Y + penSize));
g.FillPath(brush, path);
bitmap.Save("[Image Path]", ImageFormat.Png);
// Or: return (Bitmap)bitmap.Clone();
// Or: return bitmap; declaring the bitmap without a using statement
}
}
我正在从指定的文本生成图像,但我遇到了一个问题:我无法删除我生成的图像中绘制文本的顶部和底部填充。
我试图在使用 Graphics.DrawString()
时更改字符串格式,但我只设法删除了左右填充。
private void button1_Click(object sender, EventArgs e)
{
Font font = new Font("Arial", 52, FontStyle.Regular);
Image i = GetTextAsImage(textBox1.Text,400, font, Color.Black, Color.LightGray);
i.Save("myImage.jpeg", ImageFormat.Jpeg);
}
private Image GetTextAsImage(String text, int widthInPixel, Font textFont, Color textColor, Color backColor)
{
//first, create a dummy bitmap just to get a graphics object
Image img = new Bitmap(1, 1);
Graphics drawing = Graphics.FromImage(img);
//measure the string to see how big the image needs to be
SizeF textSize = drawing.MeasureString(text, textFont);
//free up the dummy image and old graphics object
img.Dispose();
drawing.Dispose();
//create a new image of the right size
img = new Bitmap((int)textSize.Width, textFont.Height);
drawing = Graphics.FromImage(img);
drawing.SmoothingMode = SmoothingMode.AntiAlias;
drawing.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
//paint the background
drawing.Clear(backColor);
//create a brush for the text
Brush textBrush = new SolidBrush(textColor);
drawing.DrawString(text, textFont, textBrush, 0, 0,StringFormat.GenericTypographic);
drawing.Save();
textBrush.Dispose();
drawing.Dispose();
return img;
}
这是我得到的输出:
这是预期的输出:
我建议您使用一种稍微不同的方法,使用 GraphicsPath class 在位图对象上测量和绘制文本。
优点是 GraphicsPath
class 报告其引用的对象将被绘制的实际坐标以及与特定字体相关的文本大小。
这些度量使用 GraphicsPath.GetBounds() 方法在 RectagleF
结构中返回。
基本构造函数假定 Pen 大小为 1 像素。
只有一个(小)细节需要注意:GDI+ 位图对象只接受以整数值表示的维度,而所有其他度量均以浮点值表示。
我们需要对舍入进行补偿,但通常只是 ± 1 像素。
结果示例:
程序说明:
- 定义字体系列和大小
- 将文本字符串添加到
GraphicsPath
对象 - 获取文本对象的
GraphicsPath
外接矩形 - 使用边界矩形大小构建位图对象
- 将世界坐标 Graphics.TranslateTransform 移动到由边界矩形
Y
位置和笔大小定义的坐标,使用它们的 负值 : 我们需要 向后移动 该措施。 - 绘制文本
另请参阅这些关于 GraphicsPath
和字体的注释:
示例代码:
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
string text = "This is my Text";
Font font = new Font("Arial", 52, FontStyle.Regular, GraphicsUnit.Point);
float penSize = 1f;
using (var path = new GraphicsPath()) {
path.AddString(text, font.FontFamily, (int)font.Style, font.Size, Point.Empty, StringFormat.GenericTypographic);
RectangleF textBounds = path.GetBounds();
using (var bitmap = new Bitmap((int)textBounds.Width, (int)textBounds.Height, PixelFormat.Format32bppArgb))
using (var g = Graphics.FromImage(bitmap))
using (var brush = new SolidBrush(Color.LightGreen)) {
g.SmoothingMode = SmoothingMode.AntiAlias;
// When rendering without a GraphicsPath object
//g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
g.Clear(Color.Black);
g.TranslateTransform(-(textBounds.X + penSize), -(textBounds.Y + penSize));
g.FillPath(brush, path);
bitmap.Save("[Image Path]", ImageFormat.Png);
// Or: return (Bitmap)bitmap.Clone();
// Or: return bitmap; declaring the bitmap without a using statement
}
}