问题描述
我正在从指定的文本生成图像,但是面临一个问题:我无法在生成的图像内部删除所绘制文本的顶部和底部填充.
I am generating images from specified text but there is a problem I'm facing: I cannot remove the top and bottom padding of the drawn Text inside the image I generate.
我尝试在使用 Graphics.DrawString()
时更改字符串格式,但是我仅设法删除了左填充和右填充.
I tried to change string format while using Graphics.DrawString()
, but I only managed to remove the left and right padding.
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 类可用于在Bitmap对象上测量和绘制文本.
I propose you a slightly different method, using the GraphicsPath class to both measure and draw the text on a Bitmap object.
优点是GraphicsPath
类报告将绘制其引用的对象的实际坐标以及与特定Font相关的文本大小.
使用RectagleF
结构返回这些度量. getbounds"rel =" nofollow noreferrer> GraphicsPath.GetBounds()方法.
基本构造函数假定Pen大小为1像素.
The advantage is that the GraphicsPath
class reports the actual coordinates where the object that it references will be drawn and also the size of the text in relation to a specific Font.
These measures are returned in a RectagleF
structure using the GraphicsPath.GetBounds() method.
The base constructor assumes a Pen size of 1 pixel.
只有一个(小)细节需要注意:GDI +位图对象仅接受以整数值表示的尺寸,而所有其他度量都以浮点值表示.
我们需要补偿四舍五入,但通常仅为±1像素.
There's only one (small) detail to take care of: the GDI+ Bitmap object accepts dimensions expressed in integer values only, while all the other measures are expressed in floating point values.
We need to compensate for the rounding, but it's usually just ± 1 pixel.
结果样本:
过程说明:
- 定义字体系列和大小
- 将文本字符串添加到
GraphicsPath
对象 - 获取文本对象的
GraphicsPath
边界矩形 - 使用边界矩形大小"构建位图对象
- 使用 Graphics.TranslateTransform移动世界坐标,使用边界矩形
Y
位置和笔大小"定义的坐标,使用它们的负值:我们需要向后移动该度量. - 绘制文字
- Define a Font Family and Size
- Add the Text string to the
GraphicsPath
object - Get the
GraphicsPath
bounding rectangle of the text object - Build a Bitmap object using the bounding rectangle Size
- Move the World coordinates, with Graphics.TranslateTransform, to the coordinates defined by the bounding rectangle
Y
position and the Pen Size, using their negative value: we need to move backwards that measure. - Draw the Text
另请参阅有关GraphicsPath
和字体的这些说明:
使用图形路径"正确绘制文本
See also these notes about GraphicsPath
and Fonts:
Properly draw text using Graphics Path
示例代码:
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
}
}
这篇关于删除图像上绘制的文本的顶部和底部填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!