winforms 从图像上绘制的文本中删除顶部和底部填充

niwlg2el  于 2022-12-14  发布在  其他
关注(0)|答案(1)|浏览(122)

我正在从指定文本生成图像,但遇到了一个问题:我无法删除我生成的图像中绘制的文本的顶部和底部填充。
我尝试在使用**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;
}

这是我得到的输出:

以下是预期输出:

41ik7eoe

41ik7eoe1#

我建议您使用一种稍微不同的方法,使用GraphicsPath类在Bitmap对象上测量和绘制文本。
其优点是GraphicsPath类报告它所包含的对象将被绘制到的实际坐标,以及与特定字体相关的文本大小。
这些度量值在**RectagleF**结构中返回,调用GraphicsPath.GetBounds()方法。
基底建构函式会假设Pen大小为1像素。
只有一个(小)细节需要注意:GDI+ Bitmap对象只接受以整数值表示的维度,而所有其他度量都以浮点值表示。
我们需要对圆角进行补偿,但通常只有± 1个像素。
结果示例:

程序描述:

  • 定义字体系列和大小
  • 将文本字符串添加到GraphicsPath对象
  • 获取文本对象的GraphicsPath边框
  • 使用边框大小生成Bitmap对象
  • 使用Graphics.TranslateTransform将“世界”坐标移动到由边界矩形Y位置和“笔大小”定义的坐标,使用它们的负值:我们需要向后移动。
  • 绘制文本

另请参阅有关GraphicsPath和字体的注解:
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 the using statement
    }
}

相关问题