删除图像上绘制的文本的顶部和底部填充 [英] Remove top and bottom padding from Text drawn on an Image

查看:108
本文介绍了删除图像上绘制的文本的顶部和底部填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从指定的文本生成图像,但是面临一个问题:我无法在生成的图像内部删除所绘制文本的顶部和底部填充.

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;
}

这是我得到的输出:

这是预期的输出:

推荐答案

我建议您使用

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
    }
}

这篇关于删除图像上绘制的文本的顶部和底部填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆